diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -1097,14 +1097,21 @@ // If the terminator of this block is branching on a constant, simplify the // terminator to an unconditional branch. This can occur due to threading in - // other blocks. - if (getKnownConstant(Condition, Preference)) { + // other blocks. We can only convert blocks that aren't LoopHeaders. It's + // non-trivial to determine if BB remains a LoopHeader and if a recurisve + // successor of BB is also a new LoopHeader. + if (!LoopHeaders.count(BB) && getKnownConstant(Condition, Preference)) { LLVM_DEBUG(dbgs() << " In block '" << BB->getName() - << "' folding terminator: " << *BB->getTerminator() + << "' trying to fold terminator: " << *BB->getTerminator() << '\n'); - ++NumFolds; - ConstantFoldTerminator(BB, true, nullptr, DTU); - return true; + if (ConstantFoldTerminator(BB, true, nullptr, DTU)) { + LLVM_DEBUG(dbgs() << " Successfully folded block '" << BB->getName() + << "' to new terminator: " << *BB->getTerminator() + << '\n'); + ++NumFolds; + return true; + } + return false; } Instruction *CondInst = dyn_cast(Condition); diff --git a/llvm/test/Transforms/JumpThreading/pr42085-thread-over-loopheader.ll b/llvm/test/Transforms/JumpThreading/pr42085-thread-over-loopheader.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/JumpThreading/pr42085-thread-over-loopheader.ll @@ -0,0 +1,35 @@ +; RUN: opt -S < %s -jump-threading | FileCheck %s + +; PR42085: Do not thread over 'body' from 'pre_body' to 'latch'. In this +; case 'body' and 'head' are the correct loop headers and must +; not be threaded over. There are no JumpThread opportunities +; in this test case. + +define i32 @test(i1 %ARG) { +; CHECK-NOT: {{.+}}.thread: +entry: + br label %pre_body + +head: + %inc_head = phi i32 [ %inc_pre_body, %pre_body ], [ %inc, %latch ] + %cmp1 = icmp sgt i32 %inc_head, 1 + br i1 %cmp1, label %body, label %pre_body + +pre_body: + %inc_pre_body = phi i32 [ 1, %entry ], [ %inc_head, %head ] + br i1 false, label %head, label %body + +body: + %res = phi i32 [ %inc_head, %head ], [ %inc_pre_body, %pre_body ] + %tmp = phi i32 [ %inc_head, %head ], [ %inc_pre_body, %pre_body ] + %inc = add i32 %tmp, 1 + br i1 %ARG, label %exit, label %latch + +latch: + %cmp2 = icmp sgt i32 %inc, 2 + br i1 %cmp2, label %exit, label %head + +exit: + %rc = phi i32 [ %res, %latch ], [ 0, %body ] + ret i32 %rc +}