diff --git a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h index 87f33c1f9ec9f..07db880a6d74b 100644 --- a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h +++ b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h @@ -95,7 +95,7 @@ class JumpThreadingPass : public PassInfoMixin { bool InsertFreezeWhenUnfoldingSelect; public: - JumpThreadingPass(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1); + JumpThreadingPass(bool InsertFreezeWhenUnfoldingSelect = true, int T = -1); // Glue for old PM. bool runImpl(Function &F, TargetLibraryInfo *TLI, TargetTransformInfo *TTI, diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 06dd9ff0a75a1..5b1f703ffef0b 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -106,7 +106,7 @@ static cl::opt PrintLVIAfterJumpThreading( static cl::opt JumpThreadingFreezeSelectCond( "jump-threading-freeze-select-cond", - cl::desc("Freeze the condition when unfolding select"), cl::init(false), + cl::desc("Freeze the condition when unfolding select"), cl::init(true), cl::Hidden); static cl::opt ThreadAcrossLoopHeaders( @@ -138,7 +138,7 @@ namespace { public: static char ID; // Pass identification - JumpThreading(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1) + JumpThreading(bool InsertFreezeWhenUnfoldingSelect = true, int T = -1) : FunctionPass(ID), Impl(InsertFreezeWhenUnfoldingSelect, T) { initializeJumpThreadingPass(*PassRegistry::getPassRegistry()); } diff --git a/llvm/test/Transforms/JumpThreading/codesize-loop.ll b/llvm/test/Transforms/JumpThreading/codesize-loop.ll index 68d6a99d86deb..3556debfed858 100644 --- a/llvm/test/Transforms/JumpThreading/codesize-loop.ll +++ b/llvm/test/Transforms/JumpThreading/codesize-loop.ll @@ -19,7 +19,8 @@ define i32 @test_minsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed ; DEFAULT-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]] ; DEFAULT-NEXT: [[TMP3:%.*]] = mul i32 [[COND]], [[TMP2]] ; DEFAULT-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[COND]], 0 -; DEFAULT-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]] +; DEFAULT-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]] +; DEFAULT-NEXT: br i1 [[COND_FR]], label [[TMP5:%.*]], label [[TMP6:%.*]] ; DEFAULT: 5: ; DEFAULT-NEXT: br label [[TMP6]] ; DEFAULT: 6: @@ -40,14 +41,15 @@ define i32 @test_minsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed ; OVERIDE-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]] ; OVERIDE-NEXT: [[TMP3:%.*]] = mul i32 [[CALL]], [[TMP2]] ; OVERIDE-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[CALL]], 0 -; OVERIDE-NEXT: br i1 [[TMP4]], label [[COND_END_THREAD]], label [[TMP6:%.*]] +; OVERIDE-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]] +; OVERIDE-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP6:%.*]] ; OVERIDE: cond.end.thread: ; OVERIDE-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[COND_END]] ], [ 205962976, [[ENTRY:%.*]] ] -; OVERIDE-NEXT: [[COND2:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ] +; OVERIDE-NEXT: [[COND3:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ] ; OVERIDE-NEXT: br label [[TMP6]] ; OVERIDE: 6: ; OVERIDE-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP5]], [[COND_END_THREAD]] ], [ [[TMP3]], [[COND_END]] ] -; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND2]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ] +; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND3]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ] ; OVERIDE-NEXT: [[TMP9:%.*]] = mul i32 [[TMP7]], [[TMP8]] ; OVERIDE-NEXT: [[CALL33:%.*]] = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 [[TMP9]]) ; OVERIDE-NEXT: ret i32 0 @@ -87,14 +89,15 @@ define i32 @test_optsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed ; DEFAULT-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]] ; DEFAULT-NEXT: [[TMP3:%.*]] = mul i32 [[CALL]], [[TMP2]] ; DEFAULT-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[CALL]], 0 -; DEFAULT-NEXT: br i1 [[TMP4]], label [[COND_END_THREAD]], label [[TMP6:%.*]] +; DEFAULT-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]] +; DEFAULT-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP6:%.*]] ; DEFAULT: cond.end.thread: ; DEFAULT-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[COND_END]] ], [ 205962976, [[ENTRY:%.*]] ] -; DEFAULT-NEXT: [[COND2:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ] +; DEFAULT-NEXT: [[COND3:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ] ; DEFAULT-NEXT: br label [[TMP6]] ; DEFAULT: 6: ; DEFAULT-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP5]], [[COND_END_THREAD]] ], [ [[TMP3]], [[COND_END]] ] -; DEFAULT-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND2]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ] +; DEFAULT-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND3]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ] ; DEFAULT-NEXT: [[TMP9:%.*]] = mul i32 [[TMP7]], [[TMP8]] ; DEFAULT-NEXT: [[CALL33:%.*]] = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 [[TMP9]]) ; DEFAULT-NEXT: ret i32 0 @@ -111,14 +114,15 @@ define i32 @test_optsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed ; OVERIDE-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]] ; OVERIDE-NEXT: [[TMP3:%.*]] = mul i32 [[CALL]], [[TMP2]] ; OVERIDE-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[CALL]], 0 -; OVERIDE-NEXT: br i1 [[TMP4]], label [[COND_END_THREAD]], label [[TMP6:%.*]] +; OVERIDE-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]] +; OVERIDE-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP6:%.*]] ; OVERIDE: cond.end.thread: ; OVERIDE-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[COND_END]] ], [ 205962976, [[ENTRY:%.*]] ] -; OVERIDE-NEXT: [[COND2:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ] +; OVERIDE-NEXT: [[COND3:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ] ; OVERIDE-NEXT: br label [[TMP6]] ; OVERIDE: 6: ; OVERIDE-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP5]], [[COND_END_THREAD]] ], [ [[TMP3]], [[COND_END]] ] -; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND2]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ] +; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND3]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ] ; OVERIDE-NEXT: [[TMP9:%.*]] = mul i32 [[TMP7]], [[TMP8]] ; OVERIDE-NEXT: [[CALL33:%.*]] = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 [[TMP9]]) ; OVERIDE-NEXT: ret i32 0 diff --git a/llvm/test/Transforms/JumpThreading/select.ll b/llvm/test/Transforms/JumpThreading/select.ll index 392cdd386ac1f..4c50be4f01309 100644 --- a/llvm/test/Transforms/JumpThreading/select.ll +++ b/llvm/test/Transforms/JumpThreading/select.ll @@ -175,7 +175,8 @@ define void @test_switch_cmp(i1 %cond, i32 %val, i8 %value) nounwind { ; CHECK: L0: ; CHECK-NEXT: [[VAL_PHI:%.*]] = phi i32 [ [[VAL:%.*]], [[ENTRY:%.*]] ] ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[VAL_PHI]], 0 -; CHECK-NEXT: br i1 [[CMP]], label [[L1:%.*]], label [[TMP0:%.*]] +; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[CMP]] +; CHECK-NEXT: br i1 [[COND_FR]], label [[L1:%.*]], label [[TMP0:%.*]] ; CHECK: 0: ; CHECK-NEXT: [[TMP1:%.*]] = phi i8 [ [[VALUE:%.*]], [[L0]] ] ; CHECK-NEXT: switch i8 [[TMP1]], label [[L3:%.*]] [ @@ -361,22 +362,23 @@ define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) noun ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[J:%.*]], 2 ; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[U:%.*]], [[V:%.*]] -; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD3:%.*]], label [[COND_FALSE_I:%.*]] +; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD4:%.*]], label [[COND_FALSE_I:%.*]] ; CHECK: cond.false.i: ; CHECK-NEXT: [[CMP4_I:%.*]] = icmp sgt i32 [[U]], [[V]] ; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD:%.*]], label [[COND_FALSE_6_I:%.*]] ; CHECK: cond.false.6.i: ; CHECK-NEXT: [[CMP8_I:%.*]] = icmp slt i32 [[W:%.*]], [[X:%.*]] -; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD3]], label [[COND_FALSE_10_I:%.*]] +; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD4]], label [[COND_FALSE_10_I:%.*]] ; CHECK: cond.false.10.i: ; CHECK-NEXT: [[CMP13_I:%.*]] = icmp sgt i32 [[W]], [[X]] ; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD]], label [[DOTEXIT:%.*]] ; CHECK: .exit: ; CHECK-NEXT: [[PHITMP:%.*]] = icmp sge i32 [[Y:%.*]], [[Z:%.*]] -; CHECK-NEXT: br i1 [[PHITMP]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD3]] +; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[PHITMP]] +; CHECK-NEXT: br i1 [[COND_FR]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD4]] ; CHECK: .exit.thread: -; CHECK-NEXT: br label [[DOTEXIT_THREAD3]] -; CHECK: .exit.thread3: +; CHECK-NEXT: br label [[DOTEXIT_THREAD4]] +; CHECK: .exit.thread4: ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[J]], [[DOTEXIT_THREAD]] ], [ [[ADD3]], [[DOTEXIT]] ], [ [[ADD3]], [[ENTRY:%.*]] ], [ [[ADD3]], [[COND_FALSE_6_I]] ] ; CHECK-NEXT: ret i32 [[TMP0]] ; @@ -416,21 +418,22 @@ define i32 @unfold4(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) noun ; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD:%.*]], label [[COND_FALSE_I:%.*]] ; CHECK: cond.false.i: ; CHECK-NEXT: [[CMP4_I:%.*]] = icmp sgt i32 [[U]], [[V]] -; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD4:%.*]], label [[COND_FALSE_6_I:%.*]] +; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD5:%.*]], label [[COND_FALSE_6_I:%.*]] ; CHECK: cond.false.6.i: ; CHECK-NEXT: [[CMP8_I:%.*]] = icmp slt i32 [[W:%.*]], [[X:%.*]] ; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD]], label [[COND_FALSE_10_I:%.*]] ; CHECK: cond.false.10.i: ; CHECK-NEXT: [[CMP13_I:%.*]] = icmp sgt i32 [[W]], [[X]] -; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD4]], label [[DOTEXIT:%.*]] +; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD5]], label [[DOTEXIT:%.*]] ; CHECK: .exit: ; CHECK-NEXT: [[CMP19_I:%.*]] = icmp sge i32 [[Y:%.*]], [[Z:%.*]] ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP19_I]] to i32 ; CHECK-NEXT: [[LNOT_I18:%.*]] = icmp eq i32 [[CONV]], 1 -; CHECK-NEXT: br i1 [[LNOT_I18]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD4]] +; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[LNOT_I18]] +; CHECK-NEXT: br i1 [[COND_FR]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD5]] ; CHECK: .exit.thread: -; CHECK-NEXT: br label [[DOTEXIT_THREAD4]] -; CHECK: .exit.thread4: +; CHECK-NEXT: br label [[DOTEXIT_THREAD5]] +; CHECK: .exit.thread5: ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[J]], [[DOTEXIT_THREAD]] ], [ [[ADD3]], [[DOTEXIT]] ], [ [[ADD3]], [[COND_FALSE_I]] ], [ [[ADD3]], [[COND_FALSE_10_I]] ] ; CHECK-NEXT: ret i32 [[TMP0]] ; @@ -625,16 +628,13 @@ sw.default: ; preds = %if.end, %sw.bb9 br label %for.cond } -; FIXME: This is an invalid transform. If %b is false and %x is poison, -; then the select produces poison (the result of the program is poison). -; But with this transform, we may be branching on poison, and that is UB. - define i32 @TryToUnfoldSelectInCurrBB(i1 %b, i1 %ui, i32 %s, i1 %x) { ; CHECK-LABEL: @TryToUnfoldSelectInCurrBB( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_END_THREAD:%.*]], label [[IF_END:%.*]] ; CHECK: if.end: -; CHECK-NEXT: br i1 [[X:%.*]], label [[TMP0:%.*]], label [[IF_END_THREAD]] +; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[X:%.*]] +; CHECK-NEXT: br i1 [[COND_FR]], label [[TMP0:%.*]], label [[IF_END_THREAD]] ; CHECK: 0: ; CHECK-NEXT: br label [[IF_END_THREAD]] ; CHECK: if.end.thread: