[llvm] [GuardWidening] Widen widenable conditions instead of widenable branches (PR #66501)

Aleksandr Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 06:13:12 PDT 2023


https://github.com/aleks-tmb updated https://github.com/llvm/llvm-project/pull/66501

>From 1923d137b65edfa80013896a3fa77a58464ad517 Mon Sep 17 00:00:00 2001
From: Aleksander Popov <apopov at azul.com>
Date: Thu, 14 Sep 2023 20:19:29 +0200
Subject: [PATCH 1/2] [GuardUtils] Revert llvm::isWidenableBranch change

In the d6e7c162e1df3736d8e2b3610a831b7cfa5be99b was introduced util to
to extract widenable conditions from branch. That util was applied in
the llvm::isWidenableBranch to check if branch is widenable. So we
consider branch is widenable if it has widenable condition anywhere in
the condition tree. But that will be true when we finish GuardWidening
reworking from branch widening to widenable conditions widening.

For now we still need to check that widenable branch is in the form of:
`br(widenable_condition & (...))`
because that form is assumed by LoopPredication and GuardWidening
algorithms.

Fixes: https://github.com/llvm/llvm-project/issues/66418
---
 llvm/lib/Analysis/GuardUtils.cpp              |  5 +-
 .../basic_widenable_branch_guards.ll          | 50 +++++++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/GuardUtils.cpp b/llvm/lib/Analysis/GuardUtils.cpp
index 83734b7eac0c823..b872286fb939618 100644
--- a/llvm/lib/Analysis/GuardUtils.cpp
+++ b/llvm/lib/Analysis/GuardUtils.cpp
@@ -24,7 +24,10 @@ bool llvm::isWidenableCondition(const Value *V) {
 }
 
 bool llvm::isWidenableBranch(const User *U) {
-  return extractWidenableCondition(U) != nullptr;
+  Value *Condition, *WidenableCondition;
+  BasicBlock *GuardedBB, *DeoptBB;
+  return parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
+                              DeoptBB);
 }
 
 bool llvm::isGuardAsWidenableBranch(const User *U) {
diff --git a/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll b/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll
index cad4fcec5c81abb..b8f7c61f6c31b8f 100644
--- a/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll
+++ b/llvm/test/Transforms/LoopPredication/basic_widenable_branch_guards.ll
@@ -2144,6 +2144,56 @@ exit:                                             ; preds = %guarded, %entry
   ret i32 %result
 }
 
+; TODO: Support widenable branch in the form of br((wc and cond0) and cond1)
+; At present LoopPredication assumes the form of br(wc && (...)) only.
+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:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[AND0:%.*]] = and i1 [[WC]], [[COND0:%.*]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[AND0]], [[COND1:%.*]]
+; CHECK-NEXT:    br i1 [[AND1]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]]
+; CHECK:       loop.preheader:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; 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:       guarded:
+; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
+; 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]]
+; CHECK:       deopt:
+; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
+; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %and0 = and i1 %wc, %cond0
+  %and1 = and i1 %and0, %cond1
+  br i1 %and1, label %loop, label %deopt
+
+loop:
+  %iv = phi i32 [ %iv.next, %guarded ], [ 0, %entry ]
+  %guard.cond = icmp sgt i32 %iv, 100
+  br i1 %guard.cond, label %deopt, label %guarded
+
+guarded:
+  %iv.next = add i32 %iv, 1
+  %exit.cond = icmp ult i32 %iv, %limit
+  br i1 %exit.cond, label %loop, label %exit
+
+deopt:
+  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
+  ret i32 %deoptcall
+exit:
+  ret i32 0
+}
+
 declare i32 @llvm.experimental.deoptimize.i32(...)
 
 ; Function Attrs: inaccessiblememonly nounwind

>From f5f22430727fd27e95c40231c02a59be28e9a125 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 2/2] 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 fb1db11e85a0b8f..af2514f1b36ec1c 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) {
@@ -225,8 +210,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.
@@ -305,16 +291,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:
@@ -360,7 +340,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 {
@@ -449,8 +429,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;
@@ -476,10 +454,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
@@ -771,18 +746,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 a58ab093a1f75d3..473cf6064acfd59 100644
--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
@@ -1009,7 +1009,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
@@ -1028,11 +1028,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;
 }
 
@@ -1095,8 +1095,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);
@@ -1130,11 +1130,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
@@ -1144,11 +1139,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
@@ -1171,7 +1166,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));
@@ -1203,7 +1198,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));
@@ -1217,7 +1212,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