Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -337,6 +337,8 @@ dbgs() << "LVI for function '" << F.getName() << "':\n"; LVI->printLVI(F, DTU.getDomTree(), dbgs()); } + if (Changed) + EliminateUnreachableBlocks(F, &DTU); return Changed; } Index: llvm/test/Transforms/JumpThreading/SimplifyUnreachableBlock.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/JumpThreading/SimplifyUnreachableBlock.ll @@ -0,0 +1,109 @@ +; RUN: opt < %s -jump-threading -S | FileCheck %s + +; JumpThreading removes the jump to bb27, then bb27 is removed, which makes +; bb28, bb31, bb32 unreachable from entry. +; But in bb11 we have +; %12 = phi i16 [ undef, %10 ], [ %21, %32 ] +; The second incoming block %32 is just made unreachable. This causes problem +; in later loop optimizations, because %21 is defined in loop body but used +; in preheader which violates LCSSA. Removing the second incoming edge of +; phinode %12 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 { + %1 = alloca i16, align 4 + %2 = load i1, i1* @c, align 4 + br i1 %2, label %5, label %3 + +3: ; preds = %0 + store i1 true, i1* @b, align 4 + store i1 true, i1* @c, align 4 + %4 = bitcast i16* %1 to i8* + call void @llvm.lifetime.start.p0i8(i64 2, i8* nonnull %4) + br label %10 + +5: ; preds = %0 + %6 = load i1, i1* @b, align 4 + %7 = bitcast i16* %1 to i8* + call void @llvm.lifetime.start.p0i8(i64 2, i8* nonnull %7) + br i1 %6, label %10, label %8 + +8: ; preds = %5 + store i16* %1, i16** @h, align 8 + br label %9 + +9: ; preds = %9, %8 + br label %9 + +10: ; preds = %5, %3 + store i1 true, i1* @d, align 4 + br label %11 + +11: ; preds = %32, %10 + %12 = phi i16 [ undef, %10 ], [ %21, %32 ] + %13 = load i1, i1* @f, align 8 + %14 = zext i1 %13 to i16 + br label %17 + +15: ; preds = %22 + %16 = icmp slt i16 %23, 77 + br i1 %16, label %25, label %27 + +17: ; preds = %25, %11 + %18 = phi i16 [ 0, %11 ], [ %26, %25 ] + %19 = phi i16 [ %12, %11 ], [ %21, %25 ] + br label %20 + +; CHECK: or +20: ; preds = %17 + %21 = or i16 %19, %14 + store i16 %21, i16* %1, align 4 + br label %22 + +22: ; preds = %20 + %23 = add i16 %18, 1 + %24 = icmp slt i16 %23, 7 + br i1 %24, label %25, label %15 + +25: ; preds = %22, %15 + %26 = phi i16 [ %23, %22 ], [ 0, %15 ] + br label %17, !llvm.loop !17 + +; This bb will be deleted because in bb15 the jump to here is removed. +27: ; preds = %15 + br label %28 + +; This bb will become unreachable because bb27 is deleted, but it +; still has predecessor %32 so it won't be trivally deleted. +; CHECK-NOT: load i1, i1* @d +28: ; preds = %27, %32 + %29 = phi i16 [ %33, %32 ], [ %23, %27 ] + %30 = load i1, i1* @d, align 4 + br i1 %30, label %32, label %31 + +; This bb will become unreachable because bb27 is deleted. +; CHECK-NOT: store i1 true, i1* @f +31: ; preds = %28 + store i1 true, i1* @f, align 8 + br label %32 + +; This bb will become unreachable because bb27 is deleted. +; CHECK-NOT: store i1 false, i1* @d +32: ; preds = %31, %28 + %33 = and i16 %29, 11 + store i1 false, i1* @d, align 4 + %34 = icmp eq i16 %33, 0 + br i1 %34, label %11, label %28, !llvm.loop !19 +} + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg %0, i8* nocapture %1) + +!17 = distinct !{!17, !18} +!18 = !{!"llvm.loop.mustprogress"} +!19 = distinct !{!19, !18}