Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -339,6 +339,9 @@ dbgs() << "LVI for function '" << F.getName() << "':\n"; LVI->printLVI(F, DTU.getDomTree(), dbgs()); } + if (Changed) + EliminateUnreachableBlocks(F, &DTU); + return Changed; } @@ -372,6 +375,7 @@ if (!Changed) return PreservedAnalyses::all(); + EliminateUnreachableBlocks(F, &DTU); PreservedAnalyses PA; PA.preserve(); PA.preserve(); Index: llvm/test/Transforms/JumpThreading/SimplifyUnreachableBlock.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/JumpThreading/SimplifyUnreachableBlock.ll @@ -0,0 +1,111 @@ +; RUN: opt < %s -jump-threading -S | FileCheck %s +; +; JumpThreading removes the jump to bb26, then bb26 is removed, which makes +; bb27, bb30, bb31 unreachable from entry. +; But in bb10 we have +; %i11 = phi i16 [ undef, %bb9 ], [ %i20, %bb31 ] +; The second incoming block bb31 is just made unreachable. This causes problem +; in later loop optimizations, because %i20 is defined in loop body but used +; in preheader which violates LCSSA. Removing the second incoming edge of +; phinode %i11 solves the problem. + +@c = internal unnamed_addr global i1 false, align 4 +@b = internal unnamed_addr global i1 false, align 4 +@h = internal unnamed_addr global i16* null, align 8 +@f = internal unnamed_addr global i1 false, align 8 +@d = internal unnamed_addr global i1 false, align 4 + +define void @j() unnamed_addr { +bb: + %i = alloca i16, align 4 + %i1 = load i1, i1* @c, align 4 + br i1 %i1, label %bb4, label %bb2 + +bb2: ; preds = %bb + store i1 true, i1* @b, align 4 + store i1 true, i1* @c, align 4 + %i3 = bitcast i16* %i to i8* + call void @llvm.lifetime.start.p0i8(i64 2, i8* nonnull %i3) + br label %bb9 + +bb4: ; preds = %bb + %i5 = load i1, i1* @b, align 4 + %i6 = bitcast i16* %i to i8* + call void @llvm.lifetime.start.p0i8(i64 2, i8* nonnull %i6) + br i1 %i5, label %bb9, label %bb7 + +bb7: ; preds = %bb4 + store i16* %i, i16** @h, align 8 + br label %bb8 + +bb8: ; preds = %bb8, %bb7 + br label %bb8 + +bb9: ; preds = %bb4, %bb2 + store i1 true, i1* @d, align 4 + br label %bb10 + +bb10: ; preds = %bb31, %bb9 + %i11 = phi i16 [ undef, %bb9 ], [ %i20, %bb31 ] + %i12 = load i1, i1* @f, align 8 + %i13 = zext i1 %i12 to i16 + br label %bb16 + +bb14: ; preds = %bb21 + %i15 = icmp slt i16 %i22, 77 + br i1 %i15, label %bb24, label %bb26 + +bb16: ; preds = %bb24, %bb10 + %i17 = phi i16 [ 0, %bb10 ], [ %i25, %bb24 ] + %i18 = phi i16 [ %i11, %bb10 ], [ %i20, %bb24 ] + br label %bb19 + +; CHECK: or +bb19: ; preds = %bb16 + %i20 = or i16 %i18, %i13 + store i16 %i20, i16* %i, align 4 + br label %bb21 + +bb21: ; preds = %bb19 + %i22 = add i16 %i17, 1 + %i23 = icmp slt i16 %i22, 7 + br i1 %i23, label %bb24, label %bb14 + +bb24: ; preds = %bb21, %bb14 + %i25 = phi i16 [ %i22, %bb21 ], [ 0, %bb14 ] + br label %bb16, !llvm.loop !0 + +bb26: ; preds = %bb14 + br label %bb27 + +; This bb will become unreachable because bb26 is deleted, but it still has +; predecessor %bb32 so it won't be trivially deleted. +; CHECK-NOT: load i1, i1* @d +bb27: ; preds = %bb31, %bb26 + %i28 = phi i16 [ %i32, %bb31 ], [ %i22, %bb26 ] + %i29 = load i1, i1* @d, align 4 + br i1 %i29, label %bb31, label %bb30 + +; This bb will become unreachable because bb26 is deleted. +; CHECK-NOT: store i1 true, i1* @f +bb30: ; preds = %bb27 + store i1 true, i1* @f, align 8 + br label %bb31 + +; This bb will become unreachable because bb26 is deleted. +; CHECK-NOT: store i1 false, i1* @d +bb31: ; preds = %bb30, %bb27 + %i32 = and i16 %i28, 11 + store i1 false, i1* @d, align 4 + %i33 = icmp eq i16 %i32, 0 + br i1 %i33, label %bb10, label %bb27, !llvm.loop !2 +} + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #0 + +attributes #0 = { argmemonly nofree nosync nounwind willreturn } + +!0 = distinct !{!0, !1} +!1 = !{!"llvm.loop.mustprogress"} +!2 = distinct !{!2, !1}