diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -26,7 +26,9 @@ #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSAUpdater.h" +#include "llvm/Analysis/MustExecute.h" #include "llvm/Analysis/Utils/Local.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" @@ -180,11 +182,14 @@ ArrayRef Invariants, bool Direction, BasicBlock &UnswitchedSucc, - BasicBlock &NormalSucc) { + BasicBlock &NormalSucc, + bool insertFreeze) { IRBuilder<> IRB(&BB); - + Value *Cond = Direction ? IRB.CreateOr(Invariants) : IRB.CreateAnd(Invariants); + if (insertFreeze) + Cond = IRB.CreateFreeze(Cond, Cond->getName() + ".fr"); IRB.CreateCondBr(Cond, Direction ? &UnswitchedSucc : &NormalSucc, Direction ? &NormalSucc : &UnswitchedSucc); } @@ -498,7 +503,7 @@ Instruction::And && "Must have an `and` of `i1`s for the condition!"); buildPartialUnswitchConditionalBranch(*OldPH, Invariants, ExitDirection, - *UnswitchedBB, *NewPH); + *UnswitchedBB, *NewPH, false); } // Update the dominator tree with the added edge. @@ -2009,6 +2014,10 @@ SE->forgetTopmostLoop(&L); } + ICFLoopSafetyInfo SafetyInfo(&DT); + SafetyInfo.computeLoopSafetyInfo(&L); + bool insertFreeze = !SafetyInfo.isGuaranteedToExecute(TI, &DT, &L); + // If the edge from this terminator to a successor dominates that successor, // store a map from each block in its dominator subtree to it. This lets us // tell when cloning for a particular successor if a block is dominated by @@ -2066,6 +2075,12 @@ BasicBlock *ClonedPH = ClonedPHs.begin()->second; BI->setSuccessor(ClonedSucc, ClonedPH); BI->setSuccessor(1 - ClonedSucc, LoopPH); + if (insertFreeze) { + auto Cond = BI->getCondition(); + if (!isGuaranteedNotToBeUndefOrPoison(Cond)) + BI->setCondition(new FreezeInst(Cond, Cond->getName() + ".fr", BI)); + } + DTUpdates.push_back({DominatorTree::Insert, SplitBB, ClonedPH}); } else { assert(SI && "Must either be a branch or switch!"); @@ -2080,6 +2095,12 @@ else Case.setSuccessor(ClonedPHs.find(Case.getCaseSuccessor())->second); + if (insertFreeze) { + auto Cond = SI->getCondition(); + if (!isGuaranteedNotToBeUndefOrPoison(Cond)) + SI->setCondition(new FreezeInst(Cond, Cond->getName() + ".fr", SI)); + } + // We need to use the set to populate domtree updates as even when there // are multiple cases pointing at the same successor we only want to // remove and insert one edge in the domtree. @@ -2156,7 +2177,7 @@ // When doing a partial unswitch, we have to do a bit more work to build up // the branch in the split block. buildPartialUnswitchConditionalBranch(*SplitBB, Invariants, Direction, - *ClonedPH, *LoopPH); + *ClonedPH, *LoopPH, insertFreeze); DTUpdates.push_back({DominatorTree::Insert, SplitBB, ClonedPH}); if (MSSAU) { diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested.ll @@ -85,8 +85,14 @@ declare void @bar() -define void @loop_nested3_conds5(i32* %addr, i1 %c1, i1 %c2, i1 %c3, i1 %c4, i1 %c5) { +define void @loop_nested3_conds5(i32* %addr, i1 %c1i, i1 %c2i, i1 %c3i, i1 %c4i, i1 %c5i) { entry: + ; c1 ~ c5 are guaranteed to be never undef or poison. + %c1 = freeze i1 %c1i + %c2 = freeze i1 %c2i + %c3 = freeze i1 %c3i + %c4 = freeze i1 %c4i + %c5 = freeze i1 %c5i %addr1 = getelementptr i32, i32* %addr, i64 0 %addr2 = getelementptr i32, i32* %addr, i64 1 %addr3 = getelementptr i32, i32* %addr, i64 2 diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-nontrivial-unswitch-nested2.ll @@ -97,8 +97,14 @@ declare void @bar() -define void @loop_nested3_conds5(i32* %addr, i1 %c1, i1 %c2, i1 %c3, i1 %c4, i1 %c5) { +define void @loop_nested3_conds5(i32* %addr, i1 %c1i, i1 %c2i, i1 %c3i, i1 %c4i, i1 %c5i) { entry: + ; c1 ~ c5 are guaranteed to be never undef or poison. + %c1 = freeze i1 %c1i + %c2 = freeze i1 %c2i + %c3 = freeze i1 %c3i + %c4 = freeze i1 %c4i + %c5 = freeze i1 %c5i %addr1 = getelementptr i32, i32* %addr, i64 0 %addr2 = getelementptr i32, i32* %addr, i64 1 %addr3 = getelementptr i32, i32* %addr, i64 2 diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/exponential-switch-unswitch.ll @@ -86,8 +86,11 @@ ; LOOP-MAX-COUNT-111: Loop at depth 2 containing: ; LOOP-MAX-NOT: Loop at depth 2 containing: -define i32 @loop_switch(i32* %addr, i32 %c1, i32 %c2) { +define i32 @loop_switch(i32* %addr, i32 %c1i, i32 %c2i) { entry: + ; c1, c2 are guaranteed to be never undef or poison. + %c1 = freeze i32 %c1i + %c2 = freeze i32 %c2i %addr1 = getelementptr i32, i32* %addr, i64 0 %addr2 = getelementptr i32, i32* %addr, i64 1 %check0 = icmp eq i32 %c2, 0 diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll b/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/guards.ll @@ -81,7 +81,8 @@ define void @test_conditional_guards(i1 %cond, i32 %N) { ; CHECK-LABEL: @test_conditional_guards( ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] +; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND:%.*]] +; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] ; CHECK: entry.split.us: ; CHECK-NEXT: br label [[LOOP_US:%.*]] ; CHECK: loop.us: diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll @@ -57,7 +57,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: call void @x() @@ -127,7 +128,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: call void @x() @@ -208,7 +210,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: call void @x() @@ -364,7 +367,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: call void @x() @@ -441,7 +445,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: call void @x() diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll @@ -814,7 +814,8 @@ ; CHECK-NEXT: %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ] ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr ; CHECK-NEXT: %[[B:.*]] = load i32, i32* %b.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_loop_begin.split.us, label %inner_loop_begin.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_loop_begin.split.us, label %inner_loop_begin.split inner_inner_loop_begin: %v1 = load i1, i1* %ptr @@ -967,7 +968,8 @@ ; CHECK-NEXT: %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ] ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr ; CHECK-NEXT: %[[B:.*]] = load i32, i32* %b.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_loop_begin.split.us, label %inner_loop_begin.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_loop_begin.split.us, label %inner_loop_begin.split inner_inner_loop_begin: %v1 = load i1, i1* %ptr @@ -1120,7 +1122,8 @@ ; CHECK-NEXT: %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ] ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr ; CHECK-NEXT: %[[B:.*]] = load i32, i32* %b.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_loop_begin.split.us, label %inner_loop_begin.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_loop_begin.split.us, label %inner_loop_begin.split inner_inner_loop_begin: %v1 = load i1, i1* %ptr @@ -1240,7 +1243,8 @@ ; CHECK-NEXT: %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ] ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr ; CHECK-NEXT: %[[B:.*]] = load i32, i32* %b.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_loop_begin.split.us, label %inner_loop_begin.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_loop_begin.split.us, label %inner_loop_begin.split inner_inner_loop_begin: %v1 = load i1, i1* %ptr @@ -1482,7 +1486,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: %a = load i32, i32* %a.ptr @@ -1562,7 +1567,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: %a = load i32, i32* %a.ptr @@ -1661,7 +1667,8 @@ br label %inner_loop_begin ; CHECK: inner_loop_ph: ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_loop_ph.split.us, label %inner_loop_ph.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_loop_ph.split.us, label %inner_loop_ph.split inner_loop_begin: call void @sink1(i32 %b) @@ -1755,7 +1762,8 @@ br label %inner_loop_begin ; CHECK: inner_loop_ph: ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_loop_ph.split.us, label %inner_loop_ph.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_loop_ph.split.us, label %inner_loop_ph.split inner_loop_begin: call void @sink1(i32 %b) @@ -1853,7 +1861,8 @@ br label %inner_inner_loop_begin ; CHECK: inner_inner_loop_ph: ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split inner_inner_loop_begin: call void @sink1(i32 %b) @@ -1961,7 +1970,8 @@ br label %inner_inner_loop_begin ; CHECK: inner_inner_loop_ph: ; CHECK-NEXT: %[[COND:.*]] = load i1, i1* %cond.ptr -; CHECK-NEXT: br i1 %[[COND]], label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %[[COND]] +; CHECK-NEXT: br i1 %[[COND_FR]], label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split inner_inner_loop_begin: call void @sink1(i32 %b) @@ -2048,7 +2058,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: %a = load i32, i32* %a.ptr @@ -2172,7 +2183,8 @@ entry: br label %loop_begin ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split +; CHECK-NEXT: %[[COND_FR:.*]] = freeze i1 %cond +; CHECK-NEXT: br i1 %[[COND_FR]], label %entry.split.us, label %entry.split loop_begin: %a = load i32, i32* %a.ptr @@ -2420,9 +2432,10 @@ ; paths to reach an inner loop after unswitching, and one of them is via the ; predecessors of the unswitched loop header. That can allow us to find the loop ; through multiple different paths. -define void @test21(i1 %a, i1 %b) { +define void @test21(i1 %a0, i1 %b) { ; CHECK-LABEL: @test21( bb: + %a = freeze i1 %a0 br label %bb3 ; CHECK-NOT: br i1 %a ; @@ -2553,7 +2566,8 @@ entry: br label %outer.header ; CHECK: entry: -; CHECK-NEXT: br i1 %arg, +; CHECK-NEXT: %[[ARG_FR:.*]] = freeze i1 %arg +; CHECK-NEXT: br i1 %[[ARG_FR]], ; ; Just verify that we unswitched the correct bits. We should call `@f` twice in ; one unswitch and `@f` and then `@g` in the other. @@ -3064,7 +3078,8 @@ entry: br label %header ; CHECK-NEXT: entry: -; CHECK-NEXT: switch i32 %arg, label %[[ENTRY_SPLIT_C:.*]] [ +; CHECK-NEXT: %arg.fr = freeze i32 %arg +; CHECK-NEXT: switch i32 %arg.fr, label %[[ENTRY_SPLIT_C:.*]] [ ; CHECK-NEXT: i32 0, label %[[ENTRY_SPLIT_A:.*]] ; CHECK-NEXT: i32 1, label %[[ENTRY_SPLIT_A]] ; CHECK-NEXT: i32 2, label %[[ENTRY_SPLIT_B:.*]] @@ -3242,11 +3257,13 @@ ; a loop exit edge as those can in some cases be special. Among other things, ; this includes an LCSSA phi with multiple entries despite being a dedicated ; exit block. -define i32 @test30(i32 %arg) { +define i32 @test30(i32 %arg0) { ; CHECK-LABEL: define i32 @test30( entry: + %arg = freeze i32 %arg0 br label %header ; CHECK-NEXT: entry: +; CHECK-NEXT: %arg = freeze i32 %arg0 ; CHECK-NEXT: switch i32 %arg, label %[[ENTRY_SPLIT_EXIT:.*]] [ ; CHECK-NEXT: i32 -1, label %[[ENTRY_SPLIT_EXIT]] ; CHECK-NEXT: i32 0, label %[[ENTRY_SPLIT_A:.*]] @@ -3426,7 +3443,8 @@ br label %c.header ; CHECK: b.header: ; CHECK-NEXT: %v1 = call i1 @cond() -; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] +; CHECK-NEXT: %[[V1_FR:.*]] = freeze i1 %v1 +; CHECK-NEXT: br i1 %[[V1_FR]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] ; ; CHECK: [[B_HEADER_SPLIT_US]]: ; CHECK-NEXT: br label %[[C_HEADER_US:.*]] @@ -3501,7 +3519,8 @@ ; CHECK: b.header: ; CHECK-NEXT: %x.b = load i32, i32* %ptr ; CHECK-NEXT: %v1 = call i1 @cond() -; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] +; CHECK-NEXT: %[[V1_FR:.*]] = freeze i1 %v1 +; CHECK-NEXT: br i1 %[[V1_FR]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] ; ; CHECK: [[B_HEADER_SPLIT_US]]: ; CHECK-NEXT: br label %[[C_HEADER_US:.*]] @@ -3589,7 +3608,8 @@ ; CHECK: b.header: ; CHECK-NEXT: %x.b = load i32, i32* %ptr ; CHECK-NEXT: %v1 = call i1 @cond() -; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] +; CHECK-NEXT: %[[V1_FR:.*]] = freeze i1 %v1 +; CHECK-NEXT: br i1 %[[V1_FR]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] ; ; CHECK: [[B_HEADER_SPLIT_US]]: ; CHECK-NEXT: br label %[[C_HEADER_US:.*]] @@ -3669,7 +3689,8 @@ ; CHECK: b.header: ; CHECK-NEXT: %x.b = load i32, i32* %ptr ; CHECK-NEXT: %v1 = call i1 @cond() -; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] +; CHECK-NEXT: %[[V1_FR:.*]] = freeze i1 %v1 +; CHECK-NEXT: br i1 %[[V1_FR]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]] ; ; CHECK: [[B_HEADER_SPLIT_US]]: ; CHECK-NEXT: br label %[[C_HEADER_US:.*]] @@ -3767,7 +3788,8 @@ br label %d.header ; CHECK: c.header: ; CHECK-NEXT: %v1 = call i1 @cond() -; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]] +; CHECK-NEXT: %[[V1_FR:.*]] = freeze i1 %v1 +; CHECK-NEXT: br i1 %[[V1_FR]], label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]] ; ; CHECK: [[C_HEADER_SPLIT_US]]: ; CHECK-NEXT: br label %[[D_HEADER_US:.*]] @@ -3880,7 +3902,8 @@ ; CHECK: c.header: ; CHECK-NEXT: %x.c = load i32, i32* %ptr ; CHECK-NEXT: %v1 = call i1 @cond() -; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]] +; CHECK-NEXT: %[[V1_FR:.*]] = freeze i1 %v1 +; CHECK-NEXT: br i1 %[[V1_FR]], label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]] ; ; CHECK: [[C_HEADER_SPLIT_US]]: ; CHECK-NEXT: br label %[[D_HEADER_US:.*]] @@ -3962,7 +3985,8 @@ ; CHECK: b.header: ; CHECK-NEXT: %x.b = load i32, i32* %ptr ; CHECK-NEXT: %v1 = call i32 @cond.i32() -; CHECK-NEXT: switch i32 %v1, label %[[B_HEADER_SPLIT:.*]] [ +; CHECK-NEXT: %[[V1_FR]] = freeze i32 %v1 +; CHECK-NEXT: switch i32 %[[V1_FR]], label %[[B_HEADER_SPLIT:.*]] [ ; CHECK-NEXT: i32 1, label %[[B_HEADER_SPLIT_US:.*]] ; CHECK-NEXT: i32 2, label %[[B_HEADER_SPLIT_US]] ; CHECK-NEXT: i32 3, label %[[B_HEADER_SPLIT_US]]