This is an archive of the discontinued LLVM Phabricator instance.

[IR] Treat callbr as special terminator (PR64215)
ClosedPublic

Authored by nikic on Aug 23 2023, 6:07 AM.

Details

Summary

isLegalToHoistInto() currently return true for callbr instructions. That means that a callbr with one successor will be considered a proper loop preheader, which may result in instructions that use the callbr return value being hoisted past it.

Fix this by adding callbr to isExceptionTerminator (with a rename to isSpecialTerminator), which also fixes similar assumptions in other places.

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

Diff Detail

Event Timeline

nikic created this revision.Aug 23 2023, 6:07 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2023, 6:07 AM
nikic requested review of this revision.Aug 23 2023, 6:07 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2023, 6:07 AM
fhahn accepted this revision.Aug 23 2023, 6:53 AM

LGTM, thanks!

This revision is now accepted and ready to land.Aug 23 2023, 6:53 AM
nickdesaulniers accepted this revision.Aug 23 2023, 8:33 AM

Thanks for the patch!
Any other call sites of Instruction::isExceptionalTerminator() that might need similar touch ups? Perhaps we should just add Instruction::CallBr to isExceptionalTerminator(unsigned OpCode)?

llvm/lib/IR/BasicBlock.cpp
399–401

Note: a callbr may produce a value, but that's optional. It's perhaps more common at the moment that callbr does not produce a value.

nikic added a comment.Aug 24 2023, 5:28 AM

Thanks for the patch!
Any other call sites of Instruction::isExceptionalTerminator() that might need similar touch ups? Perhaps we should just add Instruction::CallBr to isExceptionalTerminator(unsigned OpCode)?

Good point. For example this test crashes jump-threading:

define i32 @test() {
  %x = callbr i32 asm sideeffect "", "=r"()
  to label %bb []

bb:
  ret i32 %x
}

So yeah, I think we should add it and rename the method, though I'm not sure to what.

nikic updated this revision to Diff 553089.Aug 24 2023, 5:55 AM
nikic retitled this revision from [LICM][LoopSimplify] Create preheader for callbr (PR64215) to [IR] Treat callbr as special terminator (PR64215).
nikic edited the summary of this revision. (Show Details)

Rename isExceptionalTerminator -> isSpecialTerminator (special as in has side effect or return value) and add callbr to it. Adjust callers as appropriate.

nikic added inline comments.Aug 24 2023, 5:59 AM
llvm/lib/Transforms/Coroutines/CoroElide.cpp
230

Context for this change: TIs contains "terminators" that have no successors and are not unreachable. The only such terminator are ret, resume, and (sometimes) cleanupret. The isExceptionalTerminator check excludes resume and cleanupret, so we are left with just ret.

If found it more obvious to just spell that out, because the isExceptionalTerminator check was a bit overly vague here (e.g. things like invoke are not relevant at all).

nickdesaulniers accepted this revision.Aug 24 2023, 9:00 AM

So yeah, I think we should add it and rename the method, though I'm not sure to what.

FWIW, https://repository.tudelft.nl/islandora/object/uuid:a3bea0c0-fc6d-47a1-9b94-bf39df4aff8f?collection=education uses the phrase an "exotic terminator."

The presubmit bots seem to be failing due to git clang-format HEAD~ resulting in a difference.

This revision was landed with ongoing or failed builds.Aug 25 2023, 12:20 AM
This revision was automatically updated to reflect the committed changes.