[llvm] [GuardWidening] Widen widenable conditions instead of widenable branches (PR #66501)
Aleksandr Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 3 10:54:46 PDT 2023
https://github.com/aleks-tmb updated https://github.com/llvm/llvm-project/pull/66501
>From 8acdd4254c1e7b4e1179290c8427dc34a9762f74 Mon Sep 17 00:00:00 2001
From: Aleksander Popov <apopov at azul.com>
Date: Fri, 15 Sep 2023 12:23:29 +0200
Subject: [PATCH] Widen widenable conditions instead of widenable branches
Turn GuardWidening and LoopPredication branch widening scheme when
always `br(cond && WC)` form is maintained:
```
%wc = call i1 @widenable.condition()
%guard = and i1 %cond0, %wc
br i1 %guard ...
```
-->
```
%wide.check = and i1 %cond0, %cond1
%wc = call i1 @widenable.condition()
%guard = and i1 %%wide.check, %wc
br i1 %guard ...
```
... into the scheme of widenable conditions widening when WC is being
replaced by `NewCheck && WC`:
```
%wc = call i1 @widenable.condition()
%guard = and i1 %cond0, %wc
br i1 %guard ...
```
-->
```
%wc = call i1 @widenable.condition()
%wide.check = and i1 %cond1, %wc
%guard = and i1 %cond0, %wide.check
br i1 %guard ...
```
The change aims to avoid cases when we turn loop-invarinat branch into a
loop-variant one, like in this issue:
https://github.com/llvm/llvm-project/issues/60234
---
llvm/include/llvm/Analysis/GuardUtils.h | 20 +-----
.../llvm/Transforms/Utils/GuardUtils.h | 13 ++--
llvm/lib/Analysis/GuardUtils.cpp | 69 +-----------------
llvm/lib/Transforms/Scalar/GuardWidening.cpp | 61 ++++++----------
.../lib/Transforms/Scalar/LoopPredication.cpp | 31 ++++----
llvm/lib/Transforms/Utils/GuardUtils.cpp | 53 +++-----------
.../Transforms/GuardWidening/basic-loop.ll | 6 +-
.../basic_widenable_condition_guards.ll | 49 +++++++------
.../Transforms/GuardWidening/hoist-checks.ll | 6 +-
.../loop_invariant_widenable_condition.ll | 9 ++-
.../Transforms/GuardWidening/mixed_guards.ll | 4 +-
.../profile-based-profitability_explicit.ll | 20 +++---
.../GuardWidening/range-check-merging.ll | 29 +++++---
.../two_forms_behavior_consistency.ll | 23 +++---
.../GuardWidening/widen-cond-with-operands.ll | 4 +-
.../basic_widenable_branch_guards.ll | 10 ++-
.../LoopPredication/predicate-exits.ll | 72 +++++++++----------
17 files changed, 171 insertions(+), 308 deletions(-)
diff --git a/llvm/include/llvm/Analysis/GuardUtils.h b/llvm/include/llvm/Analysis/GuardUtils.h
index 208f08b82d98731..2cac1c9cb87b51a 100644
--- a/llvm/include/llvm/Analysis/GuardUtils.h
+++ b/llvm/include/llvm/Analysis/GuardUtils.h
@@ -36,30 +36,12 @@ bool isWidenableBranch(const User *U);
/// 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);
-
-/// Analogous to the above, but return the Uses so 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<Value *> &Checks);
+void parseWidenableGuard(const User *U, SmallVectorImpl<Value *> &Checks);
// Returns widenable_condition if it exists in the expression tree rooting from
// \p U and has only one use.
diff --git a/llvm/include/llvm/Transforms/Utils/GuardUtils.h b/llvm/include/llvm/Transforms/Utils/GuardUtils.h
index 7ab5d9ef4f23895..6e9100229fb043c 100644
--- a/llvm/include/llvm/Transforms/Utils/GuardUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/GuardUtils.h
@@ -17,6 +17,7 @@ namespace llvm {
class BranchInst;
class CallInst;
class Function;
+class Instruction;
class Value;
/// Splits control flow at point of \p Guard, replacing it with explicit branch
@@ -29,15 +30,9 @@ class Value;
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);
-
-/// Given a branch we know is widenable (defined per Analysis/GuardUtils.h),
-/// *set* it's condition such that (only) 'Cond' is known to hold on the taken
-/// path and that the branch remains widenable after transform.
-void setWidenableBranchCond(BranchInst *WidenableBR, Value *Cond);
+/// 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);
} // llvm
diff --git a/llvm/lib/Analysis/GuardUtils.cpp b/llvm/lib/Analysis/GuardUtils.cpp
index b872286fb939618..2bf4c522fe1d570 100644
--- a/llvm/lib/Analysis/GuardUtils.cpp
+++ b/llvm/lib/Analysis/GuardUtils.cpp
@@ -24,10 +24,7 @@ bool llvm::isWidenableCondition(const Value *V) {
}
bool llvm::isWidenableBranch(const User *U) {
- Value *Condition, *WidenableCondition;
- BasicBlock *GuardedBB, *DeoptBB;
- return parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
- DeoptBB);
+ return extractWidenableCondition(U) != nullptr;
}
bool llvm::isGuardAsWidenableBranch(const User *U) {
@@ -50,70 +47,6 @@ bool llvm::isGuardAsWidenableBranch(const User *U) {
return false;
}
-bool llvm::parseWidenableBranch(const User *U, Value *&Condition,
- Value *&WidenableCondition,
- BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB) {
-
- Use *C, *WC;
- if (parseWidenableBranch(const_cast<User*>(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<BranchInst>(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<Intrinsic::experimental_widenable_condition>())) {
- 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<Instruction>(Cond);
- if (!And)
- // Could be a constexpr
- return false;
-
- if (match(A, m_Intrinsic<Intrinsic::experimental_widenable_condition>()) &&
- A->hasOneUse()) {
- WC = &And->getOperandUse(0);
- C = &And->getOperandUse(1);
- return true;
- }
-
- if (match(B, m_Intrinsic<Intrinsic::experimental_widenable_condition>()) &&
- B->hasOneUse()) {
- WC = &And->getOperandUse(1);
- C = &And->getOperandUse(0);
- return true;
- }
- return false;
-}
-
template <typename CallbackType>
static void parseCondition(Value *Condition,
CallbackType RecordCheckOrWidenableCond) {
diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
index d08820b632e5c1d..fe498686be52a37 100644
--- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp
+++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
@@ -80,21 +80,6 @@ static cl::opt<bool>
namespace {
-// Get the condition of \p I. It can either be a guard or a conditional branch.
-static Value *getCondition(Instruction *I) {
- if (IntrinsicInst *GI = dyn_cast<IntrinsicInst>(I)) {
- assert(GI->getIntrinsicID() == Intrinsic::experimental_guard &&
- "Bad guard intrinsic?");
- return GI->getArgOperand(0);
- }
- Value *Cond, *WC;
- BasicBlock *IfTrueBB, *IfFalseBB;
- if (parseWidenableBranch(I, Cond, WC, IfTrueBB, IfFalseBB))
- return Cond;
-
- return cast<BranchInst>(I)->getCondition();
-}
-
// Set the condition for \p I to \p NewCond. \p I can either be a guard or a
// conditional branch.
static void setCondition(Instruction *I, Value *NewCond) {
@@ -226,8 +211,9 @@ class GuardWideningImpl {
/// Generate the logical AND of \p ChecksToHoist and \p OldCondition and make
/// it available at InsertPt
- Value *hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
- Value *OldCondition, Instruction *InsertPt);
+ void hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
+ SmallVectorImpl<Value *> &ChecksToWiden,
+ Instruction *InsertPt);
/// Adds freeze to Orig and push it as far as possible very aggressively.
/// Also replaces all uses of frozen instruction with frozen version.
@@ -306,16 +292,10 @@ class GuardWideningImpl {
SmallVectorImpl<Value *> &ChecksToWiden,
Instruction *ToWiden) {
Instruction *InsertPt = findInsertionPointForWideCondition(ToWiden);
- auto MergedCheck = mergeChecks(ChecksToHoist, ChecksToWiden, InsertPt);
- Value *Result = MergedCheck ? *MergedCheck
- : hoistChecks(ChecksToHoist,
- getCondition(ToWiden), InsertPt);
-
- if (isGuardAsWidenableBranch(ToWiden)) {
- setWidenableBranchCond(cast<BranchInst>(ToWiden), Result);
- return;
- }
- setCondition(ToWiden, Result);
+ if (auto MergedCheck = mergeChecks(ChecksToHoist, ChecksToWiden, InsertPt))
+ setCondition(ToWiden, *MergedCheck);
+ else
+ hoistChecks(ChecksToHoist, ChecksToWiden, InsertPt);
}
public:
@@ -361,7 +341,7 @@ bool GuardWideningImpl::run() {
assert(EliminatedGuardsAndBranches.empty() || Changed);
for (auto *I : EliminatedGuardsAndBranches)
if (!WidenedGuards.count(I)) {
- assert(isa<ConstantInt>(getCondition(I)) && "Should be!");
+ setCondition(I, ConstantInt::getTrue(I->getContext()));
if (isSupportedGuardInstruction(I))
eliminateGuard(I, MSSAU);
else {
@@ -450,8 +430,6 @@ bool GuardWideningImpl::eliminateInstrViaWidening(
SmallVector<Value *> ChecksToWiden;
parseWidenableGuard(BestSoFar, ChecksToWiden);
widenGuard(ChecksToHoist, ChecksToWiden, BestSoFar);
- auto NewGuardCondition = ConstantInt::getTrue(Instr->getContext());
- setCondition(Instr, NewGuardCondition);
EliminatedGuardsAndBranches.push_back(Instr);
WidenedGuards.insert(BestSoFar);
return true;
@@ -477,10 +455,7 @@ GuardWideningImpl::WideningScore GuardWideningImpl::computeWideningScore(
if (!canBeHoistedTo(ChecksToHoist, WideningPoint))
return WS_IllegalOrNegative;
- // Further in the GuardWideningImpl::hoistChecks the entire condition might be
- // widened, not the parsed list of checks. So we need to check the possibility
- // of that condition hoisting.
- if (!canBeHoistedTo(getCondition(ToWiden), WideningPoint))
+ if (!canBeHoistedTo(ChecksToWiden, WideningPoint))
return WS_IllegalOrNegative;
// If the guard was conditional executed, it may never be reached
@@ -772,18 +747,22 @@ GuardWideningImpl::mergeChecks(SmallVectorImpl<Value *> &ChecksToHoist,
return std::nullopt;
}
-Value *GuardWideningImpl::hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
- Value *OldCondition,
- Instruction *InsertPt) {
+void GuardWideningImpl::hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
+ SmallVectorImpl<Value *> &ChecksToWiden,
+ Instruction *InsertPt) {
assert(!ChecksToHoist.empty());
IRBuilder<> Builder(InsertPt);
makeAvailableAt(ChecksToHoist, InsertPt);
- makeAvailableAt(OldCondition, InsertPt);
Value *Result = Builder.CreateAnd(ChecksToHoist);
Result = freezeAndPush(Result, InsertPt);
- Result = Builder.CreateAnd(OldCondition, Result);
- Result->setName("wide.chk");
- return Result;
+ if (isGuard(InsertPt)) {
+ makeAvailableAt(ChecksToWiden, InsertPt);
+ auto Result2 = Builder.CreateAnd(ChecksToWiden);
+ Result = Builder.CreateAnd(Result2, Result);
+ Result->setName("wide.chk");
+ setCondition(InsertPt, Result);
+ } else
+ widenWidenableCondition(InsertPt, Result);
}
bool GuardWideningImpl::parseRangeChecks(
diff --git a/llvm/lib/Transforms/Scalar/LoopPredication.cpp b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
index 55079b4a42d2fae..4591b7eee345e2e 100644
--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
@@ -1012,7 +1012,7 @@ bool LoopPredication::isLoopProfitableToPredicate() {
/// 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
@@ -1031,11 +1031,11 @@ static BranchInst *FindWidenableTerminatorAboveLoop(Loop *L, LoopInfo &LI) {
break;
} while (true);
- if (BasicBlock *Pred = BB->getSinglePredecessor()) {
+ if (BasicBlock *Pred = BB->getSinglePredecessor())
if (auto *BI = dyn_cast<BranchInst>(Pred->getTerminator()))
- if (BI->getSuccessor(0) == BB && isWidenableBranch(BI))
- return BI;
- }
+ if (BI->getSuccessor(0) == BB)
+ if (auto WC = extractWidenableCondition(BI))
+ return cast<IntrinsicInst>(WC);
return nullptr;
}
@@ -1098,8 +1098,8 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
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);
@@ -1133,11 +1133,6 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
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<Instruction>(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
@@ -1147,11 +1142,11 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
const SCEV *MinEC = getMinAnalyzeableBackedgeTakenCount(*SE, *DT, L);
if (isa<SCEVCouldNotCompute>(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
@@ -1174,7 +1169,7 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
const SCEV *ExitCount = SE->getExitCount(L, ExitingBB);
if (isa<SCEVCouldNotCompute>(ExitCount) ||
ExitCount->getType()->isPointerTy() ||
- !Rewriter.isSafeToExpandAt(ExitCount, WidenableBR))
+ !Rewriter.isSafeToExpandAt(ExitCount, WidenableCondition))
continue;
const bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB));
@@ -1206,7 +1201,7 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
// context.
NewCond = B.CreateFreeze(NewCond);
- widenWidenableBranch(WidenableBR, NewCond);
+ widenWidenableCondition(WidenableCondition, NewCond);
Value *OldCond = BI->getCondition();
BI->setCondition(ConstantInt::get(OldCond->getType(), !ExitIfTrue));
@@ -1220,7 +1215,7 @@ bool LoopPredication::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
// 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;
}
diff --git a/llvm/lib/Transforms/Utils/GuardUtils.cpp b/llvm/lib/Transforms/Utils/GuardUtils.cpp
index 7c310f16d46e219..98ba962093f5460 100644
--- a/llvm/lib/Transforms/Utils/GuardUtils.cpp
+++ b/llvm/lib/Transforms/Utils/GuardUtils.cpp
@@ -78,49 +78,12 @@ void llvm::makeGuardControlFlowExplicit(Function *DeoptIntrinsic,
}
}
-
-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<Instruction>(WidenableBR->getCondition());
- // Condition is only guaranteed to dominate branch
- WCAnd->moveBefore(WidenableBR);
- }
- assert(isWidenableBranch(WidenableBR) && "preserve widenabiliy");
-}
-
-void llvm::setWidenableBranchCond(BranchInst *WidenableBR, Value *NewCond) {
- assert(isWidenableBranch(WidenableBR) && "precondition");
-
- 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
- Instruction *WCAnd = cast<Instruction>(WidenableBR->getCondition());
- // Condition is only guaranteed to dominate branch
- WCAnd->moveBefore(WidenableBR);
- C->set(NewCond);
- }
- assert(isWidenableBranch(WidenableBR) && "preserve widenabiliy");
+void llvm::widenWidenableCondition(Instruction *WidenableCondition,
+ Value *NewCond) {
+ assert(isWidenableCondition(WidenableCondition));
+ assert(WidenableCondition->hasOneUse());
+ auto U = WidenableCondition->user_back();
+ IRBuilder<> B(&*std::next(WidenableCondition->getIterator()));
+ auto WideCheck = B.CreateAnd(NewCond, WidenableCondition, "wide.check");
+ U->replaceUsesOfWith(WidenableCondition, WideCheck);
}
diff --git a/llvm/test/Transforms/GuardWidening/basic-loop.ll b/llvm/test/Transforms/GuardWidening/basic-loop.ll
index 956d920501c2cab..679ef0545205dd9 100644
--- a/llvm/test/Transforms/GuardWidening/basic-loop.ll
+++ b/llvm/test/Transforms/GuardWidening/basic-loop.ll
@@ -16,7 +16,8 @@ define void @widen_within_loop(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
; CHECK: loop:
; CHECK-NEXT: store i32 0, ptr @G, align 4
; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
-; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2_GW_FR]]
+; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND_1_GW_FR]], [[COND_0]]
+; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[TMP0]], [[COND_2_GW_FR]]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
; CHECK-NEXT: store i32 1, ptr @G, align 4
; CHECK-NEXT: store i32 2, ptr @G, align 4
@@ -44,7 +45,8 @@ define void @widen_into_preheader(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
; CHECK-NEXT: store i32 0, ptr @G, align 4
; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
-; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2_GW_FR]]
+; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[COND_1_GW_FR]], [[COND_0]]
+; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[TMP0]], [[COND_2_GW_FR]]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
diff --git a/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll b/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll
index b972814676a1e04..ab272caf3722d85 100644
--- a/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll
+++ b/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll
@@ -8,9 +8,9 @@ define void @f_0(i1 %cond_0, i1 %cond_1) {
; CHECK-LABEL: @f_0(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -52,9 +52,9 @@ define void @f_1(i1 %cond_0, i1 %cond_1) {
; CHECK-LABEL: @f_1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -114,9 +114,9 @@ define void @f_2(i32 %a, i32 %b) {
; CHECK-NEXT: [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]
; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -236,9 +236,9 @@ define void @f_4(i32 %a, i32 %b) {
; CHECK-NEXT: [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]
; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -295,8 +295,8 @@ define void @f_5(i32 %a) {
; CHECK-NEXT: [[COND_0:%.*]] = icmp ugt i32 [[A:%.*]], 7
; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
-; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
+; CHECK-NEXT: br i1 [[WIDE_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
; CHECK-NEXT: ret void
@@ -403,9 +403,9 @@ define void @f_7(i32 %a, ptr %cond_buf) {
; CHECK-NEXT: [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]
; CHECK-NEXT: [[COND_1:%.*]] = load volatile i1, ptr [[COND_BUF:%.*]], align 1
; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_3]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -491,9 +491,9 @@ define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2) {
; CHECK-NEXT: br i1 undef, label [[LOOP]], label [[LEAVE:%.*]]
; CHECK: leave:
; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_2:%.*]], [[COND_3]]
; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND3]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND3]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_2:%.*]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
; CHECK: deopt2:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -670,9 +670,9 @@ define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1) {
; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
; CHECK: outer_header:
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -764,9 +764,9 @@ define void @f_12(i32 %a0) {
; CHECK-NEXT: [[A29:%.*]] = mul i32 [[A28]], [[A28]]
; CHECK-NEXT: [[A30:%.*]] = mul i32 [[A29]], [[A29]]
; CHECK-NEXT: [[COND:%.*]] = trunc i32 [[A30]] to i1
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 true, [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -840,8 +840,8 @@ define void @f_13(i32 %a) {
; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14
; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
-; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
+; CHECK-NEXT: br i1 [[WIDE_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
; CHECK-NEXT: ret void
@@ -1034,9 +1034,9 @@ define void @swapped_wb(i1 %cond_0, i1 %cond_1) {
; CHECK-LABEL: @swapped_wb(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[WIDE_CHK]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHECK]], [[COND_0:%.*]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -1077,10 +1077,9 @@ define void @trivial_wb(i1 %cond_0) {
; CHECK-LABEL: @trivial_wb(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_0_GW_FR:%.*]] = freeze i1 [[COND_0:%.*]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND_0_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
-; CHECK-NEXT: br i1 [[TMP0]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_0_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: br i1 [[WIDE_CHECK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/GuardWidening/hoist-checks.ll b/llvm/test/Transforms/GuardWidening/hoist-checks.ll
index 7220b3d7a4a99cd..7d7f6b328ea50c0 100644
--- a/llvm/test/Transforms/GuardWidening/hoist-checks.ll
+++ b/llvm/test/Transforms/GuardWidening/hoist-checks.ll
@@ -11,14 +11,16 @@ declare i1 @llvm.experimental.widenable.condition()
define void @test() {
; CHECK-LABEL: @test(
; CHECK-NEXT: bb0:
+; CHECK-NEXT: [[GW_FREEZE:%.*]] = freeze i1 poison
; CHECK-NEXT: [[CALL0:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[AND0:%.*]] = and i1 false, [[CALL0]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[GW_FREEZE]], [[CALL0]]
+; CHECK-NEXT: [[AND0:%.*]] = and i1 false, [[WIDE_CHECK]]
; CHECK-NEXT: [[AND1:%.*]] = and i1 false, [[AND0]]
; CHECK-NEXT: br i1 [[AND1]], label [[BB1:%.*]], label [[DEOPT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[CALL1:%.*]] = call i1 @llvm.experimental.widenable.condition()
; CHECK-NEXT: [[AND2:%.*]] = and i1 poison, [[CALL1]]
-; CHECK-NEXT: br i1 [[AND2]], label [[UNREACH:%.*]], label [[DEOPT]]
+; CHECK-NEXT: br i1 true, label [[UNREACH:%.*]], label [[DEOPT]]
; CHECK: unreach:
; CHECK-NEXT: unreachable
; CHECK: deopt:
diff --git a/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll b/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll
index b528cf021ab6d08..edae7d49f80751d 100644
--- a/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll
+++ b/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll
@@ -11,13 +11,12 @@ define i32 @test_01(i32 %start, i32 %x) {
; CHECK-NEXT: [[START_GW_FR:%.*]] = freeze i32 [[START:%.*]]
; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[START_GW_FR]], [[X_GW_FR]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]]
; CHECK-NEXT: [[WC1:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND]], [[WC1]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START_GW_FR]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WC1]]
-; CHECK-NEXT: br i1 [[TMP0]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]]
+; CHECK-NEXT: br i1 [[WIDE_CHECK]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]]
; CHECK: exit_by_wc:
; CHECK-NEXT: [[RVAL1:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[IV]]) ]
; CHECK-NEXT: ret i32 [[RVAL1]]
@@ -132,12 +131,12 @@ define i32 @test_03(i32 %start, i32 %x, i1 %c) {
; CHECK-NEXT: [[START_GW_FR:%.*]] = freeze i32 [[START:%.*]]
; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[START_GW_FR]], [[X_GW_FR]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C:%.*]], [[COND]]
; CHECK-NEXT: [[WC1:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND]], [[WC1]]
+; CHECK-NEXT: [[INVARIANT:%.*]] = and i1 [[C:%.*]], [[WIDE_CHECK]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START_GW_FR]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; CHECK-NEXT: [[INVARIANT:%.*]] = and i1 [[WIDE_CHK]], [[WC1]]
; CHECK-NEXT: br i1 [[INVARIANT]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]]
; CHECK: exit_by_wc:
; CHECK-NEXT: [[RVAL1:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[IV]]) ]
diff --git a/llvm/test/Transforms/GuardWidening/mixed_guards.ll b/llvm/test/Transforms/GuardWidening/mixed_guards.ll
index e778eccf27e7c87..7f816ad086ceaf2 100644
--- a/llvm/test/Transforms/GuardWidening/mixed_guards.ll
+++ b/llvm/test/Transforms/GuardWidening/mixed_guards.ll
@@ -46,9 +46,9 @@ define void @test_02(i1 %cond_0, i1 %cond_1) {
; CHECK-LABEL: @test_02(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
diff --git a/llvm/test/Transforms/GuardWidening/profile-based-profitability_explicit.ll b/llvm/test/Transforms/GuardWidening/profile-based-profitability_explicit.ll
index 0114a6e64a8c5a0..0a660245f34fb77 100644
--- a/llvm/test/Transforms/GuardWidening/profile-based-profitability_explicit.ll
+++ b/llvm/test/Transforms/GuardWidening/profile-based-profitability_explicit.ll
@@ -7,9 +7,9 @@ define i32 @test_intrinsic_very_profitable(i32 %n, i1 %cond.1, i1 %cond.2) {
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_2_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; CHECK: deopt:
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
@@ -76,9 +76,9 @@ define i32 @test_intrinsic_profitable(i32 %n, i1 %cond.1, i1 %cond.2) {
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_2_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
@@ -145,9 +145,9 @@ define i32 @test_intrinsic_neutral(i32 %n, i1 %cond.1, i1 %cond.2) {
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_2_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
@@ -213,9 +213,9 @@ define i32 @test_intrinsic_very_unprofitable(i32 %n, i1 %cond.1, i1 %cond.2) {
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_2_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
@@ -281,9 +281,9 @@ define i32 @test_intrinsic_unprofitable(i32 %n, i1 %cond.1, i1 %cond.2) {
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[COND_2_GW_FR]], [[WIDENABLE_COND]]
+; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1]], [[WIDE_CHECK]]
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
diff --git a/llvm/test/Transforms/GuardWidening/range-check-merging.ll b/llvm/test/Transforms/GuardWidening/range-check-merging.ll
index d1bd0f84d8c868b..01923c5616916e4 100644
--- a/llvm/test/Transforms/GuardWidening/range-check-merging.ll
+++ b/llvm/test/Transforms/GuardWidening/range-check-merging.ll
@@ -90,10 +90,13 @@ define void @f_2(i32 %a, ptr %length_buf) {
; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
; CHECK-NEXT: [[X_INC2:%.*]] = or i32 [[X]], 2
; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_GW_FR]]
-; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[CHK2]]
+; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CHK1]], [[CHK0]]
+; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[TMP0]], [[CHK2]]
; CHECK-NEXT: [[X_INC3:%.*]] = or i32 [[X]], 3
; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_GW_FR]]
-; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK1]], [[CHK3]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CHK2]], [[CHK0]]
+; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[CHK1]]
+; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[TMP2]], [[CHK3]]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
; CHECK-NEXT: ret void
;
@@ -255,10 +258,13 @@ define void @f_6(i32 %x, ptr %length_buf) {
; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_GW_FR]], 2
; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]
-; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[CHK2]]
+; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CHK1]], [[CHK0]]
+; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[TMP0]], [[CHK2]]
; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_GW_FR]], 3
; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]
-; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK1]], [[CHK3]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CHK2]], [[CHK0]]
+; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[CHK1]]
+; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[TMP2]], [[CHK3]]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
; CHECK-NEXT: ret void
;
@@ -295,19 +301,20 @@ define void @f_7(i32 %x, ptr %length_buf) {
; CHECK-NEXT: [[CHK1_B:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH_B]]
; CHECK-NEXT: [[CHK1_A:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH_A]]
; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CHK1_B]], [[CHK1_A]]
-; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[TMP0]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CHK0_B]], [[CHK0_A]]
+; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[TMP1]], [[TMP0]]
; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_GW_FR]], 2
; CHECK-NEXT: [[CHK2_A:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_A]]
-; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CHK2_A]], [[CHK0_A]]
-; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[CHK0_B]], [[TMP1]]
+; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[CHK2_A]], [[CHK0_A]]
+; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[CHK0_B]], [[TMP2]]
; CHECK-NEXT: [[CHK2_B:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_B]]
-; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2_B]], [[TMP2]]
+; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2_B]], [[TMP3]]
; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_GW_FR]], 3
; CHECK-NEXT: [[CHK3_A:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_A]]
-; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[CHK3_A]], [[CHK0_A]]
-; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[CHK0_B]], [[TMP3]]
+; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[CHK3_A]], [[CHK0_A]]
+; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[CHK0_B]], [[TMP4]]
; CHECK-NEXT: [[CHK3_B:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_B]]
-; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3_B]], [[TMP4]]
+; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3_B]], [[TMP5]]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
; CHECK-NEXT: [[CHK1:%.*]] = and i1 [[CHK1_A]], [[CHK1_B]]
; CHECK-NEXT: [[CHK2:%.*]] = and i1 [[CHK2_A]], [[CHK2_B]]
diff --git a/llvm/test/Transforms/GuardWidening/two_forms_behavior_consistency.ll b/llvm/test/Transforms/GuardWidening/two_forms_behavior_consistency.ll
index 1a9ff304837e335..5783bb4d6e7d17c 100644
--- a/llvm/test/Transforms/GuardWidening/two_forms_behavior_consistency.ll
+++ b/llvm/test/Transforms/GuardWidening/two_forms_behavior_consistency.ll
@@ -25,9 +25,12 @@ define void @test_01(i32 %a, i32 %b, i32 %c, i32 %d) {
; INTRINSIC_FORM-NEXT: [[C2:%.*]] = icmp ult i32 [[IV]], [[B_GW_FR]]
; INTRINSIC_FORM-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
; INTRINSIC_FORM-NEXT: [[C3:%.*]] = icmp ult i32 [[IV]], [[C_GW_FR]]
-; INTRINSIC_FORM-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
+; INTRINSIC_FORM-NEXT: [[TMP0:%.*]] = and i1 [[C2]], [[C1]]
+; INTRINSIC_FORM-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[TMP0]], [[C3]]
; INTRINSIC_FORM-NEXT: [[C4:%.*]] = icmp ult i32 [[IV]], [[D_GW_FR]]
-; INTRINSIC_FORM-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK1]], [[C4]]
+; INTRINSIC_FORM-NEXT: [[TMP1:%.*]] = and i1 [[C3]], [[C1]]
+; INTRINSIC_FORM-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[C2]]
+; INTRINSIC_FORM-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[TMP2]], [[C4]]
; INTRINSIC_FORM-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
; INTRINSIC_FORM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK2]], [[WIDENABLE_COND]]
; INTRINSIC_FORM-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
@@ -52,13 +55,13 @@ define void @test_01(i32 %a, i32 %b, i32 %c, i32 %d) {
; BRANCH_FORM-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; BRANCH_FORM-NEXT: [[C1:%.*]] = icmp ult i32 [[IV]], [[A]]
; BRANCH_FORM-NEXT: [[C2:%.*]] = icmp ult i32 [[IV]], [[B_GW_FR]]
-; BRANCH_FORM-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
; BRANCH_FORM-NEXT: [[C3:%.*]] = icmp ult i32 [[IV]], [[C_GW_FR]]
-; BRANCH_FORM-NEXT: [[WIDE_CHK13:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
; BRANCH_FORM-NEXT: [[C4:%.*]] = icmp ult i32 [[IV]], [[D_GW_FR]]
-; BRANCH_FORM-NEXT: [[WIDE_CHK14:%.*]] = and i1 [[WIDE_CHK13]], [[C4]]
; BRANCH_FORM-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK14]], [[WIDENABLE_COND]]
+; BRANCH_FORM-NEXT: [[WIDE_CHECK14:%.*]] = and i1 [[C4]], [[WIDENABLE_COND]]
+; BRANCH_FORM-NEXT: [[WIDE_CHECK13:%.*]] = and i1 [[C3]], [[WIDE_CHECK14]]
+; BRANCH_FORM-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[C2]], [[WIDE_CHECK13]]
+; BRANCH_FORM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[C1]], [[WIDE_CHECK]]
; BRANCH_FORM-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; BRANCH_FORM: deopt:
; BRANCH_FORM-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
@@ -87,13 +90,13 @@ define void @test_01(i32 %a, i32 %b, i32 %c, i32 %d) {
; BRANCH_FORM_LICM-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; BRANCH_FORM_LICM-NEXT: [[C1:%.*]] = icmp ult i32 [[IV]], [[A]]
; BRANCH_FORM_LICM-NEXT: [[C2:%.*]] = icmp ult i32 [[IV]], [[B_GW_FR]]
-; BRANCH_FORM_LICM-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
; BRANCH_FORM_LICM-NEXT: [[C3:%.*]] = icmp ult i32 [[IV]], [[C_GW_FR]]
-; BRANCH_FORM_LICM-NEXT: [[WIDE_CHK13:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
; BRANCH_FORM_LICM-NEXT: [[C4:%.*]] = icmp ult i32 [[IV]], [[D_GW_FR]]
-; BRANCH_FORM_LICM-NEXT: [[WIDE_CHK14:%.*]] = and i1 [[WIDE_CHK13]], [[C4]]
; BRANCH_FORM_LICM-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK14]], [[WIDENABLE_COND]]
+; BRANCH_FORM_LICM-NEXT: [[WIDE_CHECK14:%.*]] = and i1 [[C4]], [[WIDENABLE_COND]]
+; BRANCH_FORM_LICM-NEXT: [[WIDE_CHECK13:%.*]] = and i1 [[C3]], [[WIDE_CHECK14]]
+; BRANCH_FORM_LICM-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[C2]], [[WIDE_CHECK13]]
+; BRANCH_FORM_LICM-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[C1]], [[WIDE_CHECK]]
; BRANCH_FORM_LICM-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
; BRANCH_FORM_LICM: deopt:
; BRANCH_FORM_LICM-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
diff --git a/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll b/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll
index dd3c15a44912c9e..5fe0ffda3c8ff09 100644
--- a/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll
+++ b/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll
@@ -12,9 +12,9 @@ define void @foo() {
; CHECK-NEXT: [[WC1:%.*]] = call i1 @llvm.experimental.widenable.condition()
; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
; CHECK-NEXT: [[CHECK:%.*]] = icmp ult i32 [[ZERO]], 0
+; CHECK-NEXT: [[C1:%.*]] = and i1 [[CHECK]], [[WC1]]
; CHECK-NEXT: [[C2:%.*]] = and i1 [[CHECK]], [[WC2]]
-; CHECK-NEXT: [[C1:%.*]] = and i1 [[WIDE_CHK]], [[WC1]]
-; CHECK-NEXT: br i1 [[C1]], label [[BB6:%.*]], label [[BB9:%.*]]
+; CHECK-NEXT: br i1 [[WIDE_CHK]], label [[BB6:%.*]], label [[BB9:%.*]]
; CHECK: bb6:
; CHECK-NEXT: br i1 true, label [[BB7:%.*]], label [[BB8:%.*]]
; CHECK: bb7:
diff --git a/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll b/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll
index b8f7c61f6c31b8f..7327a806cf5a7f5 100644
--- a/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll
+++ b/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll
@@ -2149,8 +2149,12 @@ exit: ; preds = %guarded, %entry
define i32 @wc_deep_in_expression_tree(i1 %cond0, i1 %cond1, i32 %limit) {
; CHECK-LABEL: @wc_deep_in_expression_tree(
; CHECK-NEXT: entry:
+; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LIMIT:%.*]], i32 101)
+; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 101, [[UMIN]]
+; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[TMP0]]
; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
-; CHECK-NEXT: [[AND0:%.*]] = and i1 [[WC]], [[COND0:%.*]]
+; CHECK-NEXT: [[WIDE_CHECK:%.*]] = and i1 [[TMP1]], [[WC]]
+; CHECK-NEXT: [[AND0:%.*]] = and i1 [[WIDE_CHECK]], [[COND0:%.*]]
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[AND0]], [[COND1:%.*]]
; CHECK-NEXT: br i1 [[AND1]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]]
; CHECK: loop.preheader:
@@ -2158,10 +2162,10 @@ define i32 @wc_deep_in_expression_tree(i1 %cond0, i1 %cond1, i32 %limit) {
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp sgt i32 [[IV]], 100
-; CHECK-NEXT: br i1 [[GUARD_COND]], label [[DEOPT_LOOPEXIT:%.*]], label [[GUARDED]]
+; CHECK-NEXT: br i1 false, label [[DEOPT_LOOPEXIT:%.*]], label [[GUARDED]]
; CHECK: guarded:
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp ult i32 [[IV]], [[LIMIT:%.*]]
+; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp ult i32 [[IV]], [[LIMIT]]
; CHECK-NEXT: br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: deopt.loopexit:
; CHECK-NEXT: br label [[DEOPT]]
diff --git a/llvm/test/Transforms/LoopPredication/predicate-exits.ll b/llvm/test/Transforms/LoopPredication/predicate-exits.ll
index 470ae3bdcac02f1..7c953cda50771f4 100644
--- a/llvm/test/Transforms/LoopPredication/predicate-exits.ll
+++ b/llvm/test/Transforms/LoopPredication/predicate-exits.ll
@@ -8,14 +8,14 @@ declare void @prevent_merging()
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 @@ exit:
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 @@ exit:
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 @@ exit:
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 @@ exit:
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 @@ exit:
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 @@ exit:
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 @@ exit:
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 @@ define i32 @trivial_wb(ptr %array, i32 %length, i32 %n) {
; 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 @@ guarded:
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"() ]
More information about the llvm-commits
mailing list