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 @@ -449,6 +449,21 @@ << '\n'); LoopHeaders.erase(&BB); LVI->eraseBlock(&BB); + // If the removed block is a predecessor of a loop block + // (referencing itself), then there might be PHIs that will + // be simplifiable. Preserve those to prevent invalid IR. + DeleteDeadBlock(&BB, DTU, true); + Changed = true; + continue; + } + + if (pred_size(&BB) == 1 && *pred_begin(&BB) == &BB) { + LoopHeaders.erase(&BB); + LVI->eraseBlock(&BB); + // Manually remove the terminator, otherwise the block + // deletion will see a pending reference to the Value being + // destroyed, which will trigger assertions. + BB.getTerminator()->eraseFromParent(); DeleteDeadBlock(&BB, DTU); Changed = true; continue; diff --git a/llvm/test/Transforms/JumpThreading/removed-use.ll b/llvm/test/Transforms/JumpThreading/removed-use.ll --- a/llvm/test/Transforms/JumpThreading/removed-use.ll +++ b/llvm/test/Transforms/JumpThreading/removed-use.ll @@ -2,8 +2,7 @@ ; CHECK-LABEL: @foo ; CHECK: bb6: ; CHECK-NEXT: ret void -; CHECK: bb3: -; CHECK: br label %bb3 +; CHECK-NOT: bb3: define void @foo() { entry: br i1 true, label %bb6, label %bb3 diff --git a/llvm/test/Transforms/JumpThreading/self-block.ll b/llvm/test/Transforms/JumpThreading/self-block.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/JumpThreading/self-block.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -jump-threading %s -o - | FileCheck %s + +; Verifies that a self-referencing BasicBlock gets culled. +; Note: SimplifyCFG would also clean this up but the "add" +; instruction would become self-referencing when the phi +; is simplified. +define void @test() { +; CHECK-LABEL: @test +; CHECK: bb397: +; CHECK-NEXT: ret void +; CHECK-NOT: bb243: +entry: + br i1 true, label %bb397, label %bb215 + +bb215: ; preds = %entry + br label %bb243 + +bb243: ; preds = %bb243, %bb215 + %_4792_ = phi i32 [ %_3125_, %bb243 ], [ 1, %bb215 ] + %_3125_ = add i32 %_4792_, 1 + br label %bb243 + +bb397: ; preds = %entry + ret void +} diff --git a/llvm/test/Transforms/JumpThreading/unreachable-loops.ll b/llvm/test/Transforms/JumpThreading/unreachable-loops.ll --- a/llvm/test/Transforms/JumpThreading/unreachable-loops.ll +++ b/llvm/test/Transforms/JumpThreading/unreachable-loops.ll @@ -100,10 +100,7 @@ ; CHECK-LABEL: @PR48362( ; CHECK-NEXT: cleanup.cont1500: ; CHECK-NEXT: unreachable -; CHECK: if.end1733: -; CHECK-NEXT: [[I82:%.*]] = load i32, i32* undef, align 1 -; CHECK-NEXT: [[TOBOOL1731_NOT:%.*]] = icmp eq i32 [[I82]], 0 -; CHECK-NEXT: br label [[IF_END1733:%.*]] +; CHECK-NOT: if.end1733: ; cleanup1491: ; preds = %for.body1140 switch i32 0, label %cleanup2343.loopexit4 [