This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Don't slice up PHIs when pred BB has catchswitch
ClosedPublic

Authored by aheejin on Jun 13 2022, 2:39 PM.

Details

Summary

If an integer PHI has an illegal type (according to the data layout) and
it is only used by trunc or trunc(lshr) operations, we split the PHI
into various instructions in its predecessors:
https://github.com/llvm/llvm-project/blob/6d1543a16797fa07eecea7e542df5b42422fc721/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp#L1536-L1543

So this can produce code like the following:
Before:

pred:
  ...

bb:
  %p = phi i8 [ %somevalue, %pred ], ...
  ...
  %tobool = trunc i8 %p to i1
  use %tobool
  ...

In this code, %p has an illegal integer type, i8, and its only used
in a trunc instruction later. In this case this pass puts extraction
code in its predecessors:

After:

pred:
  ...
  %t = and i8 %somevalue, 1
  %extract = icmp ne i8 %t, 0

bb:
  %p.new = phi i1 [ %extract, %pred ], ...
  use %p.new instead of %tobool

But this doesn't work if pred is a catchswitch BB because it cannot
have any non-PHI instructions. This CL ensures we bail out in that case.

Fixes https://github.com/llvm/llvm-project/issues/55803.

Diff Detail

Event Timeline

aheejin created this revision.Jun 13 2022, 2:39 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 13 2022, 2:39 PM
aheejin requested review of this revision.Jun 13 2022, 2:39 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 13 2022, 2:39 PM
aheejin added inline comments.Jun 13 2022, 2:42 PM
llvm/test/Transforms/InstCombine/catchswitch-phi.ll
62

This test is a little more complicated than I hoped, but I couldn't reduce it further. Removing any BB from here breaks the complex condition necessary to exactly trigger this bug.

dschuff accepted this revision.Jun 13 2022, 4:37 PM
dschuff added inline comments.
llvm/test/Transforms/InstCombine/catchswitch-phi.ll
60
95

So, does the IR verifier check the property that catchswitches can't have any non-PHIs? would that be sufficient to check this?
Not that I'm suggesting you change this, it's a simple condition and I don't really expect it to be brittle. Mostly I'm just wondering how this escaped and what made the resulting error not obvious.

This revision is now accepted and ready to land.Jun 13 2022, 4:37 PM
aheejin updated this revision to Diff 436608.Jun 13 2022, 5:02 PM
aheejin marked an inline comment as done.

Address comments

llvm/test/Transforms/InstCombine/catchswitch-phi.ll
95

I don't think the IR verifier runs after every pass unless you pass some option, so this pass produced an invalid IR, and that caused the crash in the inliner. But it seems opt at least checks the validity at the end, so if you run only -instcombine and if it produces an invalid IR, it will crash.

This revision was landed with ongoing or failed builds.Jun 13 2022, 6:32 PM
This revision was automatically updated to reflect the committed changes.
nikic added a subscriber: nikic.Jun 14 2022, 12:37 AM
nikic added inline comments.
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
1128

The correct way to check this is whether getFirstInsertionPt() is end().

aheejin marked an inline comment as done.Jun 14 2022, 4:44 PM
aheejin added inline comments.
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
1128

Done in D127810.