Index: llvm/include/llvm/Analysis/GuardUtils.h =================================================================== --- llvm/include/llvm/Analysis/GuardUtils.h +++ llvm/include/llvm/Analysis/GuardUtils.h @@ -36,34 +36,16 @@ /// widenable conditional branch to deopt block. bool isGuardAsWidenableBranch(const User *U); -/// If U is widenable branch looking like: -/// %cond = ... -/// %wc = call i1 @llvm.experimental.widenable.condition() -/// %branch_cond = and i1 %cond, %wc -/// br i1 %branch_cond, label %if_true_bb, label %if_false_bb ; <--- U -/// The function returns true, and the values %cond and %wc and blocks -/// %if_true_bb, if_false_bb are returned in -/// the parameters (Condition, WidenableCondition, IfTrueBB and IfFalseFF) -/// respectively. If \p U does not match this pattern, return false. -bool parseWidenableBranch(const User *U, Value *&Condition, - Value *&WidenableCondition, BasicBlock *&IfTrueBB, - BasicBlock *&IfFalseBB); - -/// Analgous to the above, but return the Uses so that that they can be -/// modified. Unlike previous version, Condition is optional and may be null. -bool parseWidenableBranch(User *U, Use *&Cond, Use *&WC, BasicBlock *&IfTrueBB, - BasicBlock *&IfFalseBB); - // The guard condition is expected to be in form of: // cond1 && cond2 && cond3 ... // or in case of widenable branch: // cond1 && cond2 && cond3 && widenable_contidion ... // Method collects the list of checks, but skips widenable_condition. -void parseWidenableGuard(const User *U, llvm::SmallVectorImpl &Checks); - +void parseWidenableGuard(const User *U, SmallVectorImpl &Checks, + bool CollectWidenableConditions = false); // Returns widenable_condition if it exists in the expression tree rooting from // \p U and has only one use. Value *extractWidenableCondition(const User *U); -} // llvm +} // namespace llvm #endif // LLVM_ANALYSIS_GUARDUTILS_H Index: llvm/include/llvm/Transforms/Utils/GuardUtils.h =================================================================== --- llvm/include/llvm/Transforms/Utils/GuardUtils.h +++ llvm/include/llvm/Transforms/Utils/GuardUtils.h @@ -30,11 +30,6 @@ void makeGuardControlFlowExplicit(Function *DeoptIntrinsic, CallInst *Guard, bool UseWC); -/// Given a branch we know is widenable (defined per Analysis/GuardUtils.h), -/// widen it such that condition 'NewCond' is also known to hold on the taken -/// path. Branch remains widenable after transform. -void widenWidenableBranch(BranchInst *WidenableBR, Value *NewCond); - /// Widen \p WidenableCondition with a \p NewCond by replacing its use with a /// 'WidenableCondition and NewCond' inserted right after \p WidenableCondition. void widenWidenableCondition(Instruction *WidenableCondition, Value *NewCond); Index: llvm/lib/Analysis/GuardUtils.cpp =================================================================== --- llvm/lib/Analysis/GuardUtils.cpp +++ llvm/lib/Analysis/GuardUtils.cpp @@ -47,70 +47,6 @@ return false; } -bool llvm::parseWidenableBranch(const User *U, Value *&Condition, - Value *&WidenableCondition, - BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB) { - - Use *C, *WC; - if (parseWidenableBranch(const_cast(U), C, WC, IfTrueBB, IfFalseBB)) { - if (C) - Condition = C->get(); - else - Condition = ConstantInt::getTrue(IfTrueBB->getContext()); - WidenableCondition = WC->get(); - return true; - } - return false; -} - -bool llvm::parseWidenableBranch(User *U, Use *&C,Use *&WC, - BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB) { - - auto *BI = dyn_cast(U); - if (!BI || !BI->isConditional()) - return false; - auto *Cond = BI->getCondition(); - if (!Cond->hasOneUse()) - return false; - - IfTrueBB = BI->getSuccessor(0); - IfFalseBB = BI->getSuccessor(1); - - if (match(Cond, m_Intrinsic())) { - WC = &BI->getOperandUse(0); - C = nullptr; - return true; - } - - // Check for two cases: - // 1) br (i1 (and A, WC())), label %IfTrue, label %IfFalse - // 2) br (i1 (and WC(), B)), label %IfTrue, label %IfFalse - // We do not check for more generalized and trees as we should canonicalize - // to the form above in instcombine. (TODO) - Value *A, *B; - if (!match(Cond, m_And(m_Value(A), m_Value(B)))) - return false; - auto *And = dyn_cast(Cond); - if (!And) - // Could be a constexpr - return false; - - if (match(A, m_Intrinsic()) && - A->hasOneUse()) { - WC = &And->getOperandUse(0); - C = &And->getOperandUse(1); - return true; - } - - if (match(B, m_Intrinsic()) && - B->hasOneUse()) { - WC = &And->getOperandUse(1); - C = &And->getOperandUse(0); - return true; - } - return false; -} - template static void parseCondition(Value *Condition, CallbackType RecordCheckOrWidenableCond) { @@ -133,13 +69,14 @@ } void llvm::parseWidenableGuard(const User *U, - llvm::SmallVectorImpl &Checks) { + llvm::SmallVectorImpl &Checks, + bool CollectWidenableConditions) { assert((isGuard(U) || isWidenableBranch(U)) && "Should be"); Value *Condition = isGuard(U) ? cast(U)->getArgOperand(0) : cast(U)->getCondition(); parseCondition(Condition, [&](Value *Check) { - if (!isWidenableCondition(Check)) + if (!isWidenableCondition(Check) || CollectWidenableConditions) Checks.push_back(Check); return true; }); Index: llvm/lib/Transforms/Scalar/LoopPredication.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopPredication.cpp +++ llvm/lib/Transforms/Scalar/LoopPredication.cpp @@ -780,7 +780,6 @@ return false; TotalWidened += WidenedChecks.size(); - // Emit the new guard condition IRBuilder<> Builder(findInsertPt(Guard, Checks)); Value *AllChecks = Builder.CreateAnd(Checks); @@ -805,17 +804,12 @@ TotalConsidered++; SmallVector Checks; SmallVector WidenedChecks; - parseWidenableGuard(BI, Checks); - // At the moment, our matching logic for wideable conditions implicitly - // assumes we preserve the form: (br (and Cond, WC())). FIXME - auto WC = extractWidenableCondition(BI); - Checks.push_back(WC); + parseWidenableGuard(BI, Checks, true); widenChecks(Checks, WidenedChecks, Expander, BI); if (WidenedChecks.empty()) return false; TotalWidened += WidenedChecks.size(); - // Emit the new guard condition IRBuilder<> Builder(findInsertPt(BI, Checks)); Value *AllChecks = Builder.CreateAnd(Checks); @@ -1009,7 +1003,7 @@ /// If we can (cheaply) find a widenable branch which controls entry into the /// loop, return it. -static BranchInst *FindWidenableTerminatorAboveLoop(Loop *L, LoopInfo &LI) { +static IntrinsicInst *FindWidenableTerminatorAboveLoop(Loop *L, LoopInfo &LI) { // Walk back through any unconditional executed blocks and see if we can find // a widenable condition which seems to control execution of this loop. Note // that we predict that maythrow calls are likely untaken and thus that it's @@ -1028,11 +1022,11 @@ break; } while (true); - if (BasicBlock *Pred = BB->getSinglePredecessor()) { + if (BasicBlock *Pred = BB->getSinglePredecessor()) if (auto *BI = dyn_cast(Pred->getTerminator())) - if (BI->getSuccessor(0) == BB && isWidenableBranch(BI)) - return BI; - } + if (BI->getSuccessor(0) == BB) + if (auto WC = extractWidenableCondition(BI)) + return cast(WC); return nullptr; } @@ -1095,8 +1089,8 @@ if (!Latch) return false; - auto *WidenableBR = FindWidenableTerminatorAboveLoop(L, *LI); - if (!WidenableBR) + auto *WidenableCondition = FindWidenableTerminatorAboveLoop(L, *LI); + if (!WidenableCondition) return false; const SCEV *LatchEC = SE->getExitCount(L, Latch); @@ -1130,11 +1124,6 @@ if (ChangedLoop) SE->forgetLoop(L); - // The insertion point for the widening should be at the widenably call, not - // at the WidenableBR. If we do this at the widenableBR, we can incorrectly - // change a loop-invariant condition to a loop-varying one. - auto *IP = cast(WidenableBR->getCondition()); - // The use of umin(all analyzeable exits) instead of latch is subtle, but // important for profitability. We may have a loop which hasn't been fully // canonicalized just yet. If the exit we chose to widen is provably never @@ -1144,11 +1133,11 @@ const SCEV *MinEC = getMinAnalyzeableBackedgeTakenCount(*SE, *DT, L); if (isa(MinEC) || MinEC->getType()->isPointerTy() || !SE->isLoopInvariant(MinEC, L) || - !Rewriter.isSafeToExpandAt(MinEC, IP)) + !Rewriter.isSafeToExpandAt(MinEC, WidenableCondition)) return ChangedLoop; - Rewriter.setInsertPoint(IP); - IRBuilder<> B(IP); + Rewriter.setInsertPoint(WidenableCondition); + IRBuilder<> B(WidenableCondition); bool InvalidateLoop = false; Value *MinECV = nullptr; // lazily generated if needed @@ -1171,7 +1160,7 @@ const SCEV *ExitCount = SE->getExitCount(L, ExitingBB); if (isa(ExitCount) || ExitCount->getType()->isPointerTy() || - !Rewriter.isSafeToExpandAt(ExitCount, WidenableBR)) + !Rewriter.isSafeToExpandAt(ExitCount, WidenableCondition)) continue; const bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB)); @@ -1203,7 +1192,7 @@ // context. NewCond = B.CreateFreeze(NewCond); - widenWidenableBranch(WidenableBR, NewCond); + widenWidenableCondition(WidenableCondition, NewCond); Value *OldCond = BI->getCondition(); BI->setCondition(ConstantInt::get(OldCond->getType(), !ExitIfTrue)); @@ -1217,7 +1206,7 @@ // should be removed next time the CFG is modified. SE->forgetLoop(L); - // Always return `true` since we have moved the WidenableBR's condition. + // Always return `true` since we have moved WidenableCondition. return true; } Index: llvm/lib/Transforms/Utils/GuardUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/GuardUtils.cpp +++ llvm/lib/Transforms/Utils/GuardUtils.cpp @@ -78,33 +78,6 @@ } } - -void llvm::widenWidenableBranch(BranchInst *WidenableBR, Value *NewCond) { - assert(isWidenableBranch(WidenableBR) && "precondition"); - - // The tempting trivially option is to produce something like this: - // br (and oldcond, newcond) where oldcond is assumed to contain a widenable - // condition, but that doesn't match the pattern parseWidenableBranch expects - // so we have to be more sophisticated. - - Use *C, *WC; - BasicBlock *IfTrueBB, *IfFalseBB; - parseWidenableBranch(WidenableBR, C, WC, IfTrueBB, IfFalseBB); - if (!C) { - // br (wc()), ... form - IRBuilder<> B(WidenableBR); - WidenableBR->setCondition(B.CreateAnd(NewCond, WC->get())); - } else { - // br (wc & C), ... form - IRBuilder<> B(WidenableBR); - C->set(B.CreateAnd(NewCond, C->get())); - Instruction *WCAnd = cast(WidenableBR->getCondition()); - // Condition is only guaranteed to dominate branch - WCAnd->moveBefore(WidenableBR); - } - assert(isWidenableBranch(WidenableBR) && "preserve widenabiliy"); -} - void llvm::widenWidenableCondition(Instruction *WidenableCondition, Value *NewCond) { assert(isWidenableCondition(WidenableCondition)); Index: llvm/test/Transforms/LoopPredication/assumes.ll =================================================================== --- llvm/test/Transforms/LoopPredication/assumes.ll +++ llvm/test/Transforms/LoopPredication/assumes.ll @@ -30,7 +30,7 @@ ; CHECK-NEXT: [[VALUE:%.*]] = load i8, ptr [[GEP_1]], align 1 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[IV_1]], [[IV_1_END]] ; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[WC]] +; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[WC]], [[TMP5]] ; CHECK-NEXT: br i1 [[TMP6]], label [[LOOP_NEXT]], label [[DEOPT:%.*]] ; CHECK: loop.next: ; CHECK-NEXT: call void @llvm.assume(i1 [[COND_1]]) Index: llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll =================================================================== --- llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll +++ llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll @@ -21,7 +21,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -91,7 +91,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -161,7 +161,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ugt i32 [[LENGTH]], [[I]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -231,7 +231,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -302,7 +302,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP2]] ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -373,7 +373,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -443,7 +443,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -514,7 +514,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP4]] ; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -586,7 +586,7 @@ ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP4]] ; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -657,7 +657,7 @@ ; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP4]] ; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -729,7 +729,7 @@ ; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -933,7 +933,7 @@ ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1009,7 +1009,7 @@ ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ [[START_J]], [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP5]] ; CHECK-NEXT: br i1 [[TMP6]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1225,8 +1225,8 @@ ; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] ; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP3]], [[TMP7]] -; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP8]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] +; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP8]], [[TMP7]] ; CHECK-NEXT: br i1 [[TMP9]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1315,9 +1315,9 @@ ; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] ; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP12:%.*]] = and i1 [[TMP3]], [[TMP7]] -; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP11]] -; CHECK-NEXT: [[TMP14:%.*]] = and i1 [[TMP13]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP12:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] +; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP7]] +; CHECK-NEXT: [[TMP14:%.*]] = and i1 [[TMP13]], [[TMP11]] ; CHECK-NEXT: br i1 [[TMP14]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1413,7 +1413,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED6]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP12:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP12:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP12]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1426,7 +1426,7 @@ ; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] ; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] ; CHECK-NEXT: [[WIDENABLE_COND4:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[TMP7]], [[WIDENABLE_COND4]] +; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[WIDENABLE_COND4]], [[TMP7]] ; CHECK-NEXT: br i1 [[TMP13]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]] ; CHECK: deopt2: ; CHECK-NEXT: [[DEOPTCALL3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1438,7 +1438,7 @@ ; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] ; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]] ; CHECK-NEXT: [[WIDENABLE_COND9:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP14:%.*]] = and i1 [[TMP11]], [[WIDENABLE_COND9]] +; CHECK-NEXT: [[TMP14:%.*]] = and i1 [[WIDENABLE_COND9]], [[TMP11]] ; CHECK-NEXT: br i1 [[TMP14]], label [[GUARDED6]], label [[DEOPT7:%.*]], !prof [[PROF0]] ; CHECK: deopt7: ; CHECK-NEXT: [[DEOPTCALL8:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1534,8 +1534,8 @@ ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[UNRELATED_COND]], [[TMP3]] -; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[UNRELATED_COND]] +; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1814,7 +1814,7 @@ ; CHECK-NEXT: [[LENGTH:%.*]] = zext i16 [[LENGTH_I16]] to i32 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP4]] ; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -1886,7 +1886,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]] ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] ; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] @@ -2085,7 +2085,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: br label [[REAL_DEOPT:%.*]] Index: llvm/test/Transforms/LoopPredication/pr61022.ll =================================================================== --- llvm/test/Transforms/LoopPredication/pr61022.ll +++ llvm/test/Transforms/LoopPredication/pr61022.ll @@ -8,7 +8,7 @@ ; CHECK-NEXT: bb: ; CHECK-NEXT: [[INST:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true -; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[INST]] +; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[INST]], [[TMP0]] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: unreached: ; CHECK-NEXT: unreachable Index: llvm/test/Transforms/LoopPredication/predicate-exits.ll =================================================================== --- llvm/test/Transforms/LoopPredication/predicate-exits.ll +++ llvm/test/Transforms/LoopPredication/predicate-exits.ll @@ -8,14 +8,14 @@ define i32 @test1(ptr %array, i32 %length, i32 %n, i1 %cond_0) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] @@ -89,14 +89,14 @@ define i32 @test_non_canonical(ptr %array, i32 %length, i1 %cond_0) { ; CHECK-LABEL: @test_non_canonical( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LENGTH:%.*]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH]], i32 [[TMP0]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] @@ -169,18 +169,18 @@ define i32 @test_two_range_checks(ptr %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) { ; CHECK-LABEL: @test_two_range_checks( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]]) ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 ; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[TMP0]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]] -; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] -; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]] +; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK2:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDE_CHECK2]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] @@ -345,14 +345,14 @@ define i32 @test_unanalyzeable_exit2(ptr %array, i32 %length, i32 %n, i1 %cond_0) { ; CHECK-LABEL: @test_unanalyzeable_exit2( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] @@ -519,10 +519,10 @@ define i32 @provably_taken(ptr %array, i1 %cond_0) { ; CHECK-LABEL: @provably_taken( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 false -; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP0]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] @@ -594,10 +594,10 @@ define i32 @provably_not_taken(ptr %array, i1 %cond_0) { ; CHECK-LABEL: @provably_not_taken( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true -; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP0]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] @@ -672,14 +672,14 @@ define i32 @unswitch_exit_form(ptr %array, i32 %length, i32 %n, i1 %cond_0) { ; CHECK-LABEL: @unswitch_exit_form( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt.loopexit: ; CHECK-NEXT: br label [[DEOPT]] @@ -755,14 +755,14 @@ define i32 @swapped_wb(ptr %array, i32 %length, i32 %n, i1 %cond_0) { ; CHECK-LABEL: @swapped_wb( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHECK]], [[COND_0:%.*]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] @@ -840,8 +840,8 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] -; CHECK-NEXT: br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] +; CHECK-NEXT: br i1 [[WIDE_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] ; CHECK-NEXT: ret i32 [[DEOPTRET]] @@ -981,18 +981,18 @@ define i32 @wb_in_loop(ptr %array, i32 %length, i32 %n, i1 %cond_0) { ; CHECK-LABEL: @wb_in_loop( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() -; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] -; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] -; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]] -; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] +; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHECK1:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] +; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP2]], [[WIDE_CHECK1]] +; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]