diff --git a/llvm/lib/CodeGen/SelectOptimize.cpp b/llvm/lib/CodeGen/SelectOptimize.cpp index 2e03ae6aec94d..0a5f0a861d48b 100644 --- a/llvm/lib/CodeGen/SelectOptimize.cpp +++ b/llvm/lib/CodeGen/SelectOptimize.cpp @@ -130,7 +130,11 @@ class SelectOptimizeImpl { class SelectLike { SelectLike(Instruction *I) : I(I) {} + /// The select (/or) instruction. Instruction *I; + /// Whether this select is inverted, "not(cond), FalseVal, TrueVal", as + /// opposed to the original condition. + bool Inverted = false; public: /// Match a select or select-like instruction, returning a SelectLike. @@ -153,14 +157,22 @@ class SelectOptimizeImpl { bool isValid() { return I; } operator bool() { return isValid(); } + /// Invert the select by inverting the condition and switching the operands. + void setInverted() { + assert(!Inverted && "Trying to invert an inverted SelectLike"); + assert(isa(getCondition()) && + cast(getCondition())->getOpcode() == + Instruction::Xor); + Inverted = true; + } + bool isInverted() const { return Inverted; } + Instruction *getI() { return I; } const Instruction *getI() const { return I; } Type *getType() const { return I->getType(); } - /// Return the condition for the SelectLike instruction. For example the - /// condition of a select or c in `or(zext(c), x)` - Value *getCondition() const { + Value *getNonInvertedCondition() const { if (auto *Sel = dyn_cast(I)) return Sel->getCondition(); // Or(zext) case @@ -177,11 +189,24 @@ class SelectOptimizeImpl { llvm_unreachable("Unhandled case in getCondition"); } + /// Return the condition for the SelectLike instruction. For example the + /// condition of a select or c in `or(zext(c), x)` + Value *getCondition() const { + Value *CC = getNonInvertedCondition(); + // For inverted conditions the CC is checked when created to be a not + // (xor) instruction. + if (Inverted) + return cast(CC)->getOperand(0); + return CC; + } + /// Return the true value for the SelectLike instruction. Note this may not /// exist for all SelectLike instructions. For example, for `or(zext(c), x)` /// the true value would be `or(x,1)`. As this value does not exist, nullptr /// is returned. - Value *getTrueValue() const { + Value *getTrueValue(bool HonorInverts = true) const { + if (Inverted && HonorInverts) + return getFalseValue(/*HonorInverts=*/false); if (auto *Sel = dyn_cast(I)) return Sel->getTrueValue(); // Or(zext) case - The true value is Or(X), so return nullptr as the value @@ -195,7 +220,9 @@ class SelectOptimizeImpl { /// Return the false value for the SelectLike instruction. For example the /// getFalseValue of a select or `x` in `or(zext(c), x)` (which is /// `select(c, x|1, x)`) - Value *getFalseValue() const { + Value *getFalseValue(bool HonorInverts = true) const { + if (Inverted && HonorInverts) + return getTrueValue(/*HonorInverts=*/false); if (auto *Sel = dyn_cast(I)) return Sel->getFalseValue(); // Or(zext) case - return the operand which is not the zext. @@ -216,8 +243,8 @@ class SelectOptimizeImpl { /// InstCostMap. This may need to be generated for select-like instructions. Scaled64 getTrueOpCost(DenseMap &InstCostMap, const TargetTransformInfo *TTI) { - if (auto *Sel = dyn_cast(I)) - if (auto *I = dyn_cast(Sel->getTrueValue())) + if (isa(I)) + if (auto *I = dyn_cast(getTrueValue())) return InstCostMap.contains(I) ? InstCostMap[I].NonPredCost : Scaled64::getZero(); @@ -242,8 +269,8 @@ class SelectOptimizeImpl { Scaled64 getFalseOpCost(DenseMap &InstCostMap, const TargetTransformInfo *TTI) { - if (auto *Sel = dyn_cast(I)) - if (auto *I = dyn_cast(Sel->getFalseValue())) + if (isa(I)) + if (auto *I = dyn_cast(getFalseValue())) return InstCostMap.contains(I) ? InstCostMap[I].NonPredCost : Scaled64::getZero(); @@ -510,9 +537,10 @@ getTrueOrFalseValue(SelectOptimizeImpl::SelectLike SI, bool isTrue, for (SelectInst *DefSI = dyn_cast(SI.getI()); DefSI != nullptr && Selects.count(DefSI); DefSI = dyn_cast(V)) { - assert(DefSI->getCondition() == SI.getCondition() && - "The condition of DefSI does not match with SI"); - V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue()); + if (DefSI->getCondition() == SI.getCondition()) + V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue()); + else // Handle inverted SI + V = (!isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue()); } if (isa(SI.getI())) { @@ -632,18 +660,19 @@ void SelectOptimizeImpl::convertProfitableSIGroups(SelectGroups &ProfSIGroups) { // Delete the unconditional branch that was just created by the split. StartBlock->getTerminator()->eraseFromParent(); - // Move any debug/pseudo instructions that were in-between the select - // group to the newly-created end block. - SmallVector DebugPseudoINS; + // Move any debug/pseudo instructions and not's that were in-between the + // select group to the newly-created end block. + SmallVector SinkInstrs; auto DIt = SI.getI()->getIterator(); while (&*DIt != LastSI.getI()) { if (DIt->isDebugOrPseudoInst()) - DebugPseudoINS.push_back(&*DIt); + SinkInstrs.push_back(&*DIt); + if (match(&*DIt, m_Not(m_Specific(SI.getCondition())))) + SinkInstrs.push_back(&*DIt); DIt++; } - for (auto *DI : DebugPseudoINS) { + for (auto *DI : SinkInstrs) DI->moveBeforePreserving(&*EndBlock->getFirstInsertionPt()); - } // Duplicate implementation for DbgRecords, the non-instruction debug-info // format. Helper lambda for moving DbgRecords to the end block. @@ -765,6 +794,13 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB, ++BBIt; continue; } + + // Skip not(select(..)), if the not is part of the same select group + if (match(NI, m_Not(m_Specific(SI.getCondition())))) { + ++BBIt; + continue; + } + // We only allow selects in the same group, not other select-like // instructions. if (!isa(NI)) @@ -773,6 +809,10 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB, SelectLike NSI = SelectLike::match(NI); if (NSI && SI.getCondition() == NSI.getCondition()) { SIGroup.push_back(NSI); + } else if (NSI && match(NSI.getCondition(), + m_Not(m_Specific(SI.getCondition())))) { + NSI.setInverted(); + SIGroup.push_back(NSI); } else break; ++BBIt; @@ -783,6 +823,12 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB, if (!isSelectKindSupported(SI)) continue; + LLVM_DEBUG({ + dbgs() << "New Select group with\n"; + for (auto SI : SIGroup) + dbgs() << " " << *SI.getI() << "\n"; + }); + SIGroups.push_back(SIGroup); } } diff --git a/llvm/test/CodeGen/AArch64/selectopt-not.ll b/llvm/test/CodeGen/AArch64/selectopt-not.ll index 7a949d11c80d0..a7939d651a2c6 100644 --- a/llvm/test/CodeGen/AArch64/selectopt-not.ll +++ b/llvm/test/CodeGen/AArch64/selectopt-not.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=neoverse-v2 -S < %s | FileCheck %s +; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=neoverse-v2 -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-STANDARD +; RUN: opt -select-optimize -mtriple=aarch64-linux-gnu -mcpu=neoverse-v2 -S -disable-loop-level-heuristics < %s | FileCheck %s --check-prefixes=CHECK,CHECK-FORCED target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32" target triple = "aarch64" @@ -29,10 +30,10 @@ define i32 @minloc1(ptr nocapture readonly %0, ptr nocapture readonly %1, ptr no ; CHECK-NEXT: [[TMP21:%.*]] = sub i64 0, [[TMP7]] ; CHECK-NEXT: br label [[DOTPREHEADER35:%.*]] ; CHECK: .preheader35: -; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT2:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[SELECT_END:%.*]] ] +; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[SELECT_END]] ] +; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT2:%.*]], [[SELECT_END]] ] +; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[SELECT_END]] ] ; CHECK-NEXT: [[TMP24:%.*]] = mul nsw i64 [[TMP23]], [[TMP11]] ; CHECK-NEXT: [[TMP25:%.*]] = getelementptr i8, ptr [[TMP19]], i64 [[TMP24]] ; CHECK-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 @@ -40,15 +41,20 @@ define i32 @minloc1(ptr nocapture readonly %0, ptr nocapture readonly %1, ptr no ; CHECK-NEXT: [[TMP28:%.*]] = icmp sge i32 [[TMP26]], [[TMP22]] ; CHECK-NEXT: [[DOTNOT33:%.*]] = and i1 [[DOT045]], [[TMP28]] ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TMP27]], i1 true, i1 [[DOTNOT33]] -; CHECK-NEXT: [[TMP29]] = select i1 [[OR_COND]], i32 [[DOTLCSSA364144]], i32 1 +; CHECK-NEXT: [[OR_COND_FROZEN:%.*]] = freeze i1 [[OR_COND]] +; CHECK-NEXT: br i1 [[OR_COND_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]] +; CHECK: select.false: +; CHECK-NEXT: br label [[SELECT_END]] +; CHECK: select.end: +; CHECK-NEXT: [[TMP29]] = phi i32 [ [[DOTLCSSA364144]], [[DOTPREHEADER35]] ], [ 1, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[DOT2]] = phi i1 [ [[DOT045]], [[DOTPREHEADER35]] ], [ true, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[TMP30]] = phi i32 [ [[TMP22]], [[DOTPREHEADER35]] ], [ [[TMP20]], [[SELECT_FALSE]] ] ; CHECK-NEXT: [[NOT_OR_COND:%.*]] = xor i1 [[OR_COND]], true -; CHECK-NEXT: [[DOT2]] = select i1 [[NOT_OR_COND]], i1 true, i1 [[DOT045]] -; CHECK-NEXT: [[TMP30]] = select i1 [[OR_COND]], i32 [[TMP22]], i32 [[TMP20]] ; CHECK-NEXT: [[IV_N]] = add nuw nsw i64 [[TMP23]], 1 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_N]], [[TMP9]] ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[DOTPREHEADER]], label [[DOTPREHEADER35]] ; CHECK: .preheader: -; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[SELECT_END]] ] ; CHECK-NEXT: ret i32 [[DOTLCSSA3641_LCSSA]] ; %4 = getelementptr i8, ptr %0, i64 40 @@ -101,53 +107,106 @@ define i32 @minloc1(ptr nocapture readonly %0, ptr nocapture readonly %1, ptr no } define i32 @minloc1_otherunusednot(ptr nocapture readonly %0, ptr nocapture readonly %1, ptr nocapture readonly %2) { -; CHECK-LABEL: @minloc1_otherunusednot( -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0:%.*]], i64 40 -; CHECK-NEXT: [[TMP5:%.*]] = load i64, ptr [[TMP4]], align 8 -; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i64 64 -; CHECK-NEXT: [[TMP7:%.*]] = load i64, ptr [[TMP6]], align 8 -; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i64 80 -; CHECK-NEXT: [[TMP9:%.*]] = load i64, ptr [[TMP8]], align 8 -; CHECK-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i64 88 -; CHECK-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 8 -; CHECK-NEXT: [[TMP12:%.*]] = load ptr, ptr [[TMP0]], align 8 -; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP1:%.*]], align 4 -; CHECK-NEXT: [[TMP14:%.*]] = sext i32 [[TMP13]] to i64 -; CHECK-NEXT: [[TMP15:%.*]] = add nsw i64 [[TMP14]], -1 -; CHECK-NEXT: [[TMP16:%.*]] = mul i64 [[TMP15]], [[TMP5]] -; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP12]], i64 [[TMP16]] -; CHECK-NEXT: [[TMP18:%.*]] = shl i64 [[TMP7]], 3 -; CHECK-NEXT: [[TMP19:%.*]] = getelementptr i8, ptr [[TMP17]], i64 [[TMP18]] -; CHECK-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP2:%.*]], align 4 -; CHECK-NEXT: [[DOTNOT:%.*]] = icmp slt i64 [[TMP9]], 1 -; CHECK-NEXT: br i1 [[DOTNOT]], label [[DOTPREHEADER:%.*]], label [[DOTPREHEADER35_LR_PH:%.*]] -; CHECK: .preheader35.lr.ph: -; CHECK-NEXT: [[TMP21:%.*]] = sub i64 0, [[TMP7]] -; CHECK-NEXT: br label [[DOTPREHEADER35:%.*]] -; CHECK: .preheader35: -; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT2:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[TMP24:%.*]] = mul nsw i64 [[TMP23]], [[TMP11]] -; CHECK-NEXT: [[TMP25:%.*]] = getelementptr i8, ptr [[TMP19]], i64 [[TMP24]] -; CHECK-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -; CHECK-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], [[TMP20]] -; CHECK-NEXT: [[TMP28:%.*]] = icmp sge i32 [[TMP26]], [[TMP22]] -; CHECK-NEXT: [[DOTNOT33:%.*]] = and i1 [[DOT045]], [[TMP28]] -; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TMP27]], i1 true, i1 [[DOTNOT33]] -; CHECK-NEXT: [[TMP29]] = select i1 [[OR_COND]], i32 [[DOTLCSSA364144]], i32 1 -; CHECK-NEXT: [[DOT2]] = select i1 [[OR_COND]], i1 [[DOT045]], i1 true -; CHECK-NEXT: [[NOT_OR_COND:%.*]] = xor i1 [[OR_COND]], true -; CHECK-NEXT: [[TMP30]] = select i1 [[OR_COND]], i32 [[TMP22]], i32 [[TMP20]] -; CHECK-NEXT: [[IV_N]] = add nuw nsw i64 [[TMP23]], 1 -; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_N]], [[TMP9]] -; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[DOTPREHEADER]], label [[DOTPREHEADER35]] -; CHECK: .preheader: -; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[P:%.*]] = phi i1 [ false, [[TMP3]] ], [ [[NOT_OR_COND]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[Q:%.*]] = select i1 [[P]], i32 [[DOTLCSSA3641_LCSSA]], i32 1 -; CHECK-NEXT: ret i32 [[Q]] +; CHECK-STANDARD-LABEL: @minloc1_otherunusednot( +; CHECK-STANDARD-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0:%.*]], i64 40 +; CHECK-STANDARD-NEXT: [[TMP5:%.*]] = load i64, ptr [[TMP4]], align 8 +; CHECK-STANDARD-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i64 64 +; CHECK-STANDARD-NEXT: [[TMP7:%.*]] = load i64, ptr [[TMP6]], align 8 +; CHECK-STANDARD-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i64 80 +; CHECK-STANDARD-NEXT: [[TMP9:%.*]] = load i64, ptr [[TMP8]], align 8 +; CHECK-STANDARD-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i64 88 +; CHECK-STANDARD-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 8 +; CHECK-STANDARD-NEXT: [[TMP12:%.*]] = load ptr, ptr [[TMP0]], align 8 +; CHECK-STANDARD-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP1:%.*]], align 4 +; CHECK-STANDARD-NEXT: [[TMP14:%.*]] = sext i32 [[TMP13]] to i64 +; CHECK-STANDARD-NEXT: [[TMP15:%.*]] = add nsw i64 [[TMP14]], -1 +; CHECK-STANDARD-NEXT: [[TMP16:%.*]] = mul i64 [[TMP15]], [[TMP5]] +; CHECK-STANDARD-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP12]], i64 [[TMP16]] +; CHECK-STANDARD-NEXT: [[TMP18:%.*]] = shl i64 [[TMP7]], 3 +; CHECK-STANDARD-NEXT: [[TMP19:%.*]] = getelementptr i8, ptr [[TMP17]], i64 [[TMP18]] +; CHECK-STANDARD-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP2:%.*]], align 4 +; CHECK-STANDARD-NEXT: [[DOTNOT:%.*]] = icmp slt i64 [[TMP9]], 1 +; CHECK-STANDARD-NEXT: br i1 [[DOTNOT]], label [[DOTPREHEADER:%.*]], label [[DOTPREHEADER35_LR_PH:%.*]] +; CHECK-STANDARD: .preheader35.lr.ph: +; CHECK-STANDARD-NEXT: [[TMP21:%.*]] = sub i64 0, [[TMP7]] +; CHECK-STANDARD-NEXT: br label [[DOTPREHEADER35:%.*]] +; CHECK-STANDARD: .preheader35: +; CHECK-STANDARD-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[DOTPREHEADER35]] ] +; CHECK-STANDARD-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[DOTPREHEADER35]] ] +; CHECK-STANDARD-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT2:%.*]], [[DOTPREHEADER35]] ] +; CHECK-STANDARD-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[DOTPREHEADER35]] ] +; CHECK-STANDARD-NEXT: [[TMP24:%.*]] = mul nsw i64 [[TMP23]], [[TMP11]] +; CHECK-STANDARD-NEXT: [[TMP25:%.*]] = getelementptr i8, ptr [[TMP19]], i64 [[TMP24]] +; CHECK-STANDARD-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 +; CHECK-STANDARD-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], [[TMP20]] +; CHECK-STANDARD-NEXT: [[TMP28:%.*]] = icmp sge i32 [[TMP26]], [[TMP22]] +; CHECK-STANDARD-NEXT: [[DOTNOT33:%.*]] = and i1 [[DOT045]], [[TMP28]] +; CHECK-STANDARD-NEXT: [[OR_COND:%.*]] = select i1 [[TMP27]], i1 true, i1 [[DOTNOT33]] +; CHECK-STANDARD-NEXT: [[TMP29]] = select i1 [[OR_COND]], i32 [[DOTLCSSA364144]], i32 1 +; CHECK-STANDARD-NEXT: [[DOT2]] = select i1 [[OR_COND]], i1 [[DOT045]], i1 true +; CHECK-STANDARD-NEXT: [[NOT_OR_COND:%.*]] = xor i1 [[OR_COND]], true +; CHECK-STANDARD-NEXT: [[TMP30]] = select i1 [[OR_COND]], i32 [[TMP22]], i32 [[TMP20]] +; CHECK-STANDARD-NEXT: [[IV_N]] = add nuw nsw i64 [[TMP23]], 1 +; CHECK-STANDARD-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_N]], [[TMP9]] +; CHECK-STANDARD-NEXT: br i1 [[EXITCOND_NOT]], label [[DOTPREHEADER]], label [[DOTPREHEADER35]] +; CHECK-STANDARD: .preheader: +; CHECK-STANDARD-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[DOTPREHEADER35]] ] +; CHECK-STANDARD-NEXT: [[P:%.*]] = phi i1 [ false, [[TMP3]] ], [ [[NOT_OR_COND]], [[DOTPREHEADER35]] ] +; CHECK-STANDARD-NEXT: [[Q:%.*]] = select i1 [[P]], i32 [[DOTLCSSA3641_LCSSA]], i32 1 +; CHECK-STANDARD-NEXT: ret i32 [[Q]] +; +; CHECK-FORCED-LABEL: @minloc1_otherunusednot( +; CHECK-FORCED-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0:%.*]], i64 40 +; CHECK-FORCED-NEXT: [[TMP5:%.*]] = load i64, ptr [[TMP4]], align 8 +; CHECK-FORCED-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i64 64 +; CHECK-FORCED-NEXT: [[TMP7:%.*]] = load i64, ptr [[TMP6]], align 8 +; CHECK-FORCED-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i64 80 +; CHECK-FORCED-NEXT: [[TMP9:%.*]] = load i64, ptr [[TMP8]], align 8 +; CHECK-FORCED-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i64 88 +; CHECK-FORCED-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 8 +; CHECK-FORCED-NEXT: [[TMP12:%.*]] = load ptr, ptr [[TMP0]], align 8 +; CHECK-FORCED-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP1:%.*]], align 4 +; CHECK-FORCED-NEXT: [[TMP14:%.*]] = sext i32 [[TMP13]] to i64 +; CHECK-FORCED-NEXT: [[TMP15:%.*]] = add nsw i64 [[TMP14]], -1 +; CHECK-FORCED-NEXT: [[TMP16:%.*]] = mul i64 [[TMP15]], [[TMP5]] +; CHECK-FORCED-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP12]], i64 [[TMP16]] +; CHECK-FORCED-NEXT: [[TMP18:%.*]] = shl i64 [[TMP7]], 3 +; CHECK-FORCED-NEXT: [[TMP19:%.*]] = getelementptr i8, ptr [[TMP17]], i64 [[TMP18]] +; CHECK-FORCED-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP2:%.*]], align 4 +; CHECK-FORCED-NEXT: [[DOTNOT:%.*]] = icmp slt i64 [[TMP9]], 1 +; CHECK-FORCED-NEXT: br i1 [[DOTNOT]], label [[DOTPREHEADER:%.*]], label [[DOTPREHEADER35_LR_PH:%.*]] +; CHECK-FORCED: .preheader35.lr.ph: +; CHECK-FORCED-NEXT: [[TMP21:%.*]] = sub i64 0, [[TMP7]] +; CHECK-FORCED-NEXT: br label [[DOTPREHEADER35:%.*]] +; CHECK-FORCED: .preheader35: +; CHECK-FORCED-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[SELECT_END:%.*]] ] +; CHECK-FORCED-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[SELECT_END]] ] +; CHECK-FORCED-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT2:%.*]], [[SELECT_END]] ] +; CHECK-FORCED-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[SELECT_END]] ] +; CHECK-FORCED-NEXT: [[TMP24:%.*]] = mul nsw i64 [[TMP23]], [[TMP11]] +; CHECK-FORCED-NEXT: [[TMP25:%.*]] = getelementptr i8, ptr [[TMP19]], i64 [[TMP24]] +; CHECK-FORCED-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 +; CHECK-FORCED-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], [[TMP20]] +; CHECK-FORCED-NEXT: [[TMP28:%.*]] = icmp sge i32 [[TMP26]], [[TMP22]] +; CHECK-FORCED-NEXT: [[DOTNOT33:%.*]] = and i1 [[DOT045]], [[TMP28]] +; CHECK-FORCED-NEXT: [[OR_COND:%.*]] = select i1 [[TMP27]], i1 true, i1 [[DOTNOT33]] +; CHECK-FORCED-NEXT: [[OR_COND_FROZEN:%.*]] = freeze i1 [[OR_COND]] +; CHECK-FORCED-NEXT: br i1 [[OR_COND_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]] +; CHECK-FORCED: select.false: +; CHECK-FORCED-NEXT: br label [[SELECT_END]] +; CHECK-FORCED: select.end: +; CHECK-FORCED-NEXT: [[TMP29]] = phi i32 [ [[DOTLCSSA364144]], [[DOTPREHEADER35]] ], [ 1, [[SELECT_FALSE]] ] +; CHECK-FORCED-NEXT: [[DOT2]] = phi i1 [ [[DOT045]], [[DOTPREHEADER35]] ], [ true, [[SELECT_FALSE]] ] +; CHECK-FORCED-NEXT: [[TMP30]] = phi i32 [ [[TMP22]], [[DOTPREHEADER35]] ], [ [[TMP20]], [[SELECT_FALSE]] ] +; CHECK-FORCED-NEXT: [[NOT_OR_COND:%.*]] = xor i1 [[OR_COND]], true +; CHECK-FORCED-NEXT: [[IV_N]] = add nuw nsw i64 [[TMP23]], 1 +; CHECK-FORCED-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_N]], [[TMP9]] +; CHECK-FORCED-NEXT: br i1 [[EXITCOND_NOT]], label [[DOTPREHEADER]], label [[DOTPREHEADER35]] +; CHECK-FORCED: .preheader: +; CHECK-FORCED-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[SELECT_END]] ] +; CHECK-FORCED-NEXT: [[P:%.*]] = phi i1 [ false, [[TMP3]] ], [ [[NOT_OR_COND]], [[SELECT_END]] ] +; CHECK-FORCED-NEXT: [[Q:%.*]] = select i1 [[P]], i32 [[DOTLCSSA3641_LCSSA]], i32 1 +; CHECK-FORCED-NEXT: ret i32 [[Q]] ; %4 = getelementptr i8, ptr %0, i64 40 %5 = load i64, ptr %4, align 8 @@ -225,10 +284,10 @@ define i32 @minloc1_twonot(ptr nocapture readonly %0, ptr nocapture readonly %1, ; CHECK-NEXT: [[TMP21:%.*]] = sub i64 0, [[TMP7]] ; CHECK-NEXT: br label [[DOTPREHEADER35:%.*]] ; CHECK: .preheader35: -; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT3:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[SELECT_END:%.*]] ] +; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[SELECT_END]] ] +; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT3:%.*]], [[SELECT_END]] ] +; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[SELECT_END]] ] ; CHECK-NEXT: [[TMP24:%.*]] = mul nsw i64 [[TMP23]], [[TMP11]] ; CHECK-NEXT: [[TMP25:%.*]] = getelementptr i8, ptr [[TMP19]], i64 [[TMP24]] ; CHECK-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 @@ -236,16 +295,21 @@ define i32 @minloc1_twonot(ptr nocapture readonly %0, ptr nocapture readonly %1, ; CHECK-NEXT: [[TMP28:%.*]] = icmp sge i32 [[TMP26]], [[TMP22]] ; CHECK-NEXT: [[DOTNOT33:%.*]] = and i1 [[DOT045]], [[TMP28]] ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TMP27]], i1 true, i1 [[DOTNOT33]] -; CHECK-NEXT: [[TMP29]] = select i1 [[OR_COND]], i32 [[DOTLCSSA364144]], i32 1 +; CHECK-NEXT: [[OR_COND_FROZEN:%.*]] = freeze i1 [[OR_COND]] +; CHECK-NEXT: br i1 [[OR_COND_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]] +; CHECK: select.false: +; CHECK-NEXT: br label [[SELECT_END]] +; CHECK: select.end: +; CHECK-NEXT: [[TMP29]] = phi i32 [ [[DOTLCSSA364144]], [[DOTPREHEADER35]] ], [ 1, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[DOT2:%.*]] = phi i1 [ [[DOT045]], [[DOTPREHEADER35]] ], [ true, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[DOT3]] = phi i1 [ [[DOT045]], [[DOTPREHEADER35]] ], [ true, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[TMP30]] = phi i32 [ [[TMP22]], [[DOTPREHEADER35]] ], [ [[TMP20]], [[SELECT_FALSE]] ] ; CHECK-NEXT: [[NOT_OR_COND:%.*]] = xor i1 [[OR_COND]], true -; CHECK-NEXT: [[DOT2:%.*]] = select i1 [[NOT_OR_COND]], i1 true, i1 [[DOT045]] -; CHECK-NEXT: [[DOT3]] = select i1 [[NOT_OR_COND]], i1 true, i1 [[DOT2]] -; CHECK-NEXT: [[TMP30]] = select i1 [[OR_COND]], i32 [[TMP22]], i32 [[TMP20]] ; CHECK-NEXT: [[IV_N]] = add nuw nsw i64 [[TMP23]], 1 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_N]], [[TMP9]] ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[DOTPREHEADER]], label [[DOTPREHEADER35]] ; CHECK: .preheader: -; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[SELECT_END]] ] ; CHECK-NEXT: ret i32 [[DOTLCSSA3641_LCSSA]] ; %4 = getelementptr i8, ptr %0, i64 40 @@ -323,10 +387,10 @@ define i32 @minloc1_onenotdependent(ptr nocapture readonly %0, ptr nocapture rea ; CHECK-NEXT: [[TMP21:%.*]] = sub i64 0, [[TMP7]] ; CHECK-NEXT: br label [[DOTPREHEADER35:%.*]] ; CHECK: .preheader35: -; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT3:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP30:%.*]], [[SELECT_END:%.*]] ] +; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[IV_N:%.*]], [[SELECT_END]] ] +; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT3:%.*]], [[SELECT_END]] ] +; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP29:%.*]], [[SELECT_END]] ] ; CHECK-NEXT: [[TMP24:%.*]] = mul nsw i64 [[TMP23]], [[TMP11]] ; CHECK-NEXT: [[TMP25:%.*]] = getelementptr i8, ptr [[TMP19]], i64 [[TMP24]] ; CHECK-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 @@ -334,16 +398,21 @@ define i32 @minloc1_onenotdependent(ptr nocapture readonly %0, ptr nocapture rea ; CHECK-NEXT: [[TMP28:%.*]] = icmp sge i32 [[TMP26]], [[TMP22]] ; CHECK-NEXT: [[DOTNOT33:%.*]] = and i1 [[DOT045]], [[TMP28]] ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TMP27]], i1 true, i1 [[DOTNOT33]] -; CHECK-NEXT: [[TMP29]] = select i1 [[OR_COND]], i32 [[DOTLCSSA364144]], i32 1 +; CHECK-NEXT: [[OR_COND_FROZEN:%.*]] = freeze i1 [[OR_COND]] +; CHECK-NEXT: br i1 [[OR_COND_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]] +; CHECK: select.false: +; CHECK-NEXT: br label [[SELECT_END]] +; CHECK: select.end: +; CHECK-NEXT: [[TMP29]] = phi i32 [ [[DOTLCSSA364144]], [[DOTPREHEADER35]] ], [ 1, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[DOT2:%.*]] = phi i1 [ true, [[DOTPREHEADER35]] ], [ [[DOT045]], [[SELECT_FALSE]] ] +; CHECK-NEXT: [[DOT3]] = phi i1 [ true, [[DOTPREHEADER35]] ], [ true, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[TMP30]] = phi i32 [ [[TMP22]], [[DOTPREHEADER35]] ], [ [[TMP20]], [[SELECT_FALSE]] ] ; CHECK-NEXT: [[NOT_OR_COND:%.*]] = xor i1 [[OR_COND]], true -; CHECK-NEXT: [[DOT2:%.*]] = select i1 [[OR_COND]], i1 true, i1 [[DOT045]] -; CHECK-NEXT: [[DOT3]] = select i1 [[NOT_OR_COND]], i1 true, i1 [[DOT2]] -; CHECK-NEXT: [[TMP30]] = select i1 [[OR_COND]], i32 [[TMP22]], i32 [[TMP20]] ; CHECK-NEXT: [[IV_N]] = add nuw nsw i64 [[TMP23]], 1 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_N]], [[TMP9]] ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[DOTPREHEADER]], label [[DOTPREHEADER35]] ; CHECK: .preheader: -; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP29]], [[SELECT_END]] ] ; CHECK-NEXT: ret i32 [[DOTLCSSA3641_LCSSA]] ; %4 = getelementptr i8, ptr %0, i64 40 @@ -429,10 +498,10 @@ define i32 @minloc9(ptr nocapture readonly %0, ptr nocapture readonly %1, ptr no ; CHECK-NEXT: [[DOTNEG55:%.*]] = mul i64 [[TMP7]], -8 ; CHECK-NEXT: br label [[DOTPREHEADER35:%.*]] ; CHECK: .preheader35: -; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP78:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP79:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT2_8:%.*]], [[DOTPREHEADER35]] ] -; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP77:%.*]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[TMP22:%.*]] = phi i32 [ 2147483647, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP78:%.*]], [[SELECT_END15:%.*]] ] +; CHECK-NEXT: [[TMP23:%.*]] = phi i64 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP79:%.*]], [[SELECT_END15]] ] +; CHECK-NEXT: [[DOT045:%.*]] = phi i1 [ false, [[DOTPREHEADER35_LR_PH]] ], [ [[DOT2_8:%.*]], [[SELECT_END15]] ] +; CHECK-NEXT: [[DOTLCSSA364144:%.*]] = phi i32 [ 0, [[DOTPREHEADER35_LR_PH]] ], [ [[TMP77:%.*]], [[SELECT_END15]] ] ; CHECK-NEXT: [[TMP24:%.*]] = mul nsw i64 [[TMP23]], [[TMP11]] ; CHECK-NEXT: [[TMP25:%.*]] = getelementptr i8, ptr [[TMP19]], i64 [[TMP24]] ; CHECK-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 @@ -440,95 +509,140 @@ define i32 @minloc9(ptr nocapture readonly %0, ptr nocapture readonly %1, ptr no ; CHECK-NEXT: [[TMP28:%.*]] = icmp sge i32 [[TMP26]], [[TMP22]] ; CHECK-NEXT: [[DOTNOT33:%.*]] = and i1 [[DOT045]], [[TMP28]] ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TMP27]], i1 true, i1 [[DOTNOT33]] -; CHECK-NEXT: [[TMP29:%.*]] = select i1 [[OR_COND]], i32 [[DOTLCSSA364144]], i32 1 +; CHECK-NEXT: [[OR_COND_FROZEN:%.*]] = freeze i1 [[OR_COND]] +; CHECK-NEXT: br i1 [[OR_COND_FROZEN]], label [[SELECT_END:%.*]], label [[SELECT_FALSE:%.*]] +; CHECK: select.false: +; CHECK-NEXT: br label [[SELECT_END]] +; CHECK: select.end: +; CHECK-NEXT: [[TMP29:%.*]] = phi i32 [ [[DOTLCSSA364144]], [[DOTPREHEADER35]] ], [ 1, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[DOT2:%.*]] = phi i1 [ [[DOT045]], [[DOTPREHEADER35]] ], [ true, [[SELECT_FALSE]] ] +; CHECK-NEXT: [[TMP30:%.*]] = phi i32 [ [[TMP22]], [[DOTPREHEADER35]] ], [ [[TMP20]], [[SELECT_FALSE]] ] ; CHECK-NEXT: [[NOT_OR_COND:%.*]] = xor i1 [[OR_COND]], true -; CHECK-NEXT: [[DOT2:%.*]] = select i1 [[NOT_OR_COND]], i1 true, i1 [[DOT045]] -; CHECK-NEXT: [[TMP30:%.*]] = select i1 [[OR_COND]], i32 [[TMP22]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP31:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[TMP21]] ; CHECK-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 ; CHECK-NEXT: [[TMP33:%.*]] = icmp ne i32 [[TMP32]], [[TMP20]] ; CHECK-NEXT: [[TMP34:%.*]] = icmp sge i32 [[TMP32]], [[TMP30]] ; CHECK-NEXT: [[DOTNOT33_1:%.*]] = and i1 [[DOT2]], [[TMP34]] ; CHECK-NEXT: [[OR_COND_1:%.*]] = select i1 [[TMP33]], i1 true, i1 [[DOTNOT33_1]] -; CHECK-NEXT: [[TMP35:%.*]] = select i1 [[OR_COND_1]], i32 [[TMP29]], i32 2 +; CHECK-NEXT: [[OR_COND_1_FROZEN:%.*]] = freeze i1 [[OR_COND_1]] +; CHECK-NEXT: br i1 [[OR_COND_1_FROZEN]], label [[SELECT_END1:%.*]], label [[SELECT_FALSE2:%.*]] +; CHECK: select.false2: +; CHECK-NEXT: br label [[SELECT_END1]] +; CHECK: select.end1: +; CHECK-NEXT: [[TMP35:%.*]] = phi i32 [ [[TMP29]], [[SELECT_END]] ], [ 2, [[SELECT_FALSE2]] ] +; CHECK-NEXT: [[DOT2_1:%.*]] = phi i1 [ [[DOT2]], [[SELECT_END]] ], [ true, [[SELECT_FALSE2]] ] +; CHECK-NEXT: [[TMP36:%.*]] = phi i32 [ [[TMP30]], [[SELECT_END]] ], [ [[TMP20]], [[SELECT_FALSE2]] ] ; CHECK-NEXT: [[NOT_OR_COND_1:%.*]] = xor i1 [[OR_COND_1]], true -; CHECK-NEXT: [[DOT2_1:%.*]] = select i1 [[NOT_OR_COND_1]], i1 true, i1 [[DOT2]] -; CHECK-NEXT: [[TMP36:%.*]] = select i1 [[OR_COND_1]], i32 [[TMP30]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP37:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[DOTNEG]] ; CHECK-NEXT: [[TMP38:%.*]] = load i32, ptr [[TMP37]], align 4 ; CHECK-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], [[TMP20]] ; CHECK-NEXT: [[TMP40:%.*]] = icmp sge i32 [[TMP38]], [[TMP36]] ; CHECK-NEXT: [[DOTNOT33_2:%.*]] = and i1 [[DOT2_1]], [[TMP40]] ; CHECK-NEXT: [[OR_COND_2:%.*]] = select i1 [[TMP39]], i1 true, i1 [[DOTNOT33_2]] -; CHECK-NEXT: [[TMP41:%.*]] = select i1 [[OR_COND_2]], i32 [[TMP35]], i32 3 +; CHECK-NEXT: [[OR_COND_2_FROZEN:%.*]] = freeze i1 [[OR_COND_2]] +; CHECK-NEXT: br i1 [[OR_COND_2_FROZEN]], label [[SELECT_END3:%.*]], label [[SELECT_FALSE4:%.*]] +; CHECK: select.false4: +; CHECK-NEXT: br label [[SELECT_END3]] +; CHECK: select.end3: +; CHECK-NEXT: [[TMP41:%.*]] = phi i32 [ [[TMP35]], [[SELECT_END1]] ], [ 3, [[SELECT_FALSE4]] ] +; CHECK-NEXT: [[DOT2_2:%.*]] = phi i1 [ [[DOT2_1]], [[SELECT_END1]] ], [ true, [[SELECT_FALSE4]] ] +; CHECK-NEXT: [[TMP42:%.*]] = phi i32 [ [[TMP36]], [[SELECT_END1]] ], [ [[TMP20]], [[SELECT_FALSE4]] ] ; CHECK-NEXT: [[NOT_OR_COND_2:%.*]] = xor i1 [[OR_COND_2]], true -; CHECK-NEXT: [[DOT2_2:%.*]] = select i1 [[NOT_OR_COND_2]], i1 true, i1 [[DOT2_1]] -; CHECK-NEXT: [[TMP42:%.*]] = select i1 [[OR_COND_2]], i32 [[TMP36]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP43:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[DOTNEG50]] ; CHECK-NEXT: [[TMP44:%.*]] = load i32, ptr [[TMP43]], align 4 ; CHECK-NEXT: [[TMP45:%.*]] = icmp ne i32 [[TMP44]], [[TMP20]] ; CHECK-NEXT: [[TMP46:%.*]] = icmp sge i32 [[TMP44]], [[TMP42]] ; CHECK-NEXT: [[DOTNOT33_3:%.*]] = and i1 [[DOT2_2]], [[TMP46]] ; CHECK-NEXT: [[OR_COND_3:%.*]] = select i1 [[TMP45]], i1 true, i1 [[DOTNOT33_3]] -; CHECK-NEXT: [[TMP47:%.*]] = select i1 [[OR_COND_3]], i32 [[TMP41]], i32 4 +; CHECK-NEXT: [[OR_COND_3_FROZEN:%.*]] = freeze i1 [[OR_COND_3]] +; CHECK-NEXT: br i1 [[OR_COND_3_FROZEN]], label [[SELECT_END5:%.*]], label [[SELECT_FALSE6:%.*]] +; CHECK: select.false6: +; CHECK-NEXT: br label [[SELECT_END5]] +; CHECK: select.end5: +; CHECK-NEXT: [[TMP47:%.*]] = phi i32 [ [[TMP41]], [[SELECT_END3]] ], [ 4, [[SELECT_FALSE6]] ] +; CHECK-NEXT: [[DOT2_3:%.*]] = phi i1 [ [[DOT2_2]], [[SELECT_END3]] ], [ true, [[SELECT_FALSE6]] ] +; CHECK-NEXT: [[TMP48:%.*]] = phi i32 [ [[TMP42]], [[SELECT_END3]] ], [ [[TMP20]], [[SELECT_FALSE6]] ] ; CHECK-NEXT: [[NOT_OR_COND_3:%.*]] = xor i1 [[OR_COND_3]], true -; CHECK-NEXT: [[DOT2_3:%.*]] = select i1 [[NOT_OR_COND_3]], i1 true, i1 [[DOT2_2]] -; CHECK-NEXT: [[TMP48:%.*]] = select i1 [[OR_COND_3]], i32 [[TMP42]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP49:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[DOTNEG51]] ; CHECK-NEXT: [[TMP50:%.*]] = load i32, ptr [[TMP49]], align 4 ; CHECK-NEXT: [[TMP51:%.*]] = icmp ne i32 [[TMP50]], [[TMP20]] ; CHECK-NEXT: [[TMP52:%.*]] = icmp sge i32 [[TMP50]], [[TMP48]] ; CHECK-NEXT: [[DOTNOT33_4:%.*]] = and i1 [[DOT2_3]], [[TMP52]] ; CHECK-NEXT: [[OR_COND_4:%.*]] = select i1 [[TMP51]], i1 true, i1 [[DOTNOT33_4]] -; CHECK-NEXT: [[TMP53:%.*]] = select i1 [[OR_COND_4]], i32 [[TMP47]], i32 5 +; CHECK-NEXT: [[OR_COND_4_FROZEN:%.*]] = freeze i1 [[OR_COND_4]] +; CHECK-NEXT: br i1 [[OR_COND_4_FROZEN]], label [[SELECT_END7:%.*]], label [[SELECT_FALSE8:%.*]] +; CHECK: select.false8: +; CHECK-NEXT: br label [[SELECT_END7]] +; CHECK: select.end7: +; CHECK-NEXT: [[TMP53:%.*]] = phi i32 [ [[TMP47]], [[SELECT_END5]] ], [ 5, [[SELECT_FALSE8]] ] +; CHECK-NEXT: [[DOT2_4:%.*]] = phi i1 [ [[DOT2_3]], [[SELECT_END5]] ], [ true, [[SELECT_FALSE8]] ] +; CHECK-NEXT: [[TMP54:%.*]] = phi i32 [ [[TMP48]], [[SELECT_END5]] ], [ [[TMP20]], [[SELECT_FALSE8]] ] ; CHECK-NEXT: [[NOT_OR_COND_4:%.*]] = xor i1 [[OR_COND_4]], true -; CHECK-NEXT: [[DOT2_4:%.*]] = select i1 [[NOT_OR_COND_4]], i1 true, i1 [[DOT2_3]] -; CHECK-NEXT: [[TMP54:%.*]] = select i1 [[OR_COND_4]], i32 [[TMP48]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP55:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[DOTNEG52]] ; CHECK-NEXT: [[TMP56:%.*]] = load i32, ptr [[TMP55]], align 4 ; CHECK-NEXT: [[TMP57:%.*]] = icmp ne i32 [[TMP56]], [[TMP20]] ; CHECK-NEXT: [[TMP58:%.*]] = icmp sge i32 [[TMP56]], [[TMP54]] ; CHECK-NEXT: [[DOTNOT33_5:%.*]] = and i1 [[DOT2_4]], [[TMP58]] ; CHECK-NEXT: [[OR_COND_5:%.*]] = select i1 [[TMP57]], i1 true, i1 [[DOTNOT33_5]] -; CHECK-NEXT: [[TMP59:%.*]] = select i1 [[OR_COND_5]], i32 [[TMP53]], i32 6 +; CHECK-NEXT: [[OR_COND_5_FROZEN:%.*]] = freeze i1 [[OR_COND_5]] +; CHECK-NEXT: br i1 [[OR_COND_5_FROZEN]], label [[SELECT_END9:%.*]], label [[SELECT_FALSE10:%.*]] +; CHECK: select.false10: +; CHECK-NEXT: br label [[SELECT_END9]] +; CHECK: select.end9: +; CHECK-NEXT: [[TMP59:%.*]] = phi i32 [ [[TMP53]], [[SELECT_END7]] ], [ 6, [[SELECT_FALSE10]] ] +; CHECK-NEXT: [[DOT2_5:%.*]] = phi i1 [ [[DOT2_4]], [[SELECT_END7]] ], [ true, [[SELECT_FALSE10]] ] +; CHECK-NEXT: [[TMP60:%.*]] = phi i32 [ [[TMP54]], [[SELECT_END7]] ], [ [[TMP20]], [[SELECT_FALSE10]] ] ; CHECK-NEXT: [[NOT_OR_COND_5:%.*]] = xor i1 [[OR_COND_5]], true -; CHECK-NEXT: [[DOT2_5:%.*]] = select i1 [[NOT_OR_COND_5]], i1 true, i1 [[DOT2_4]] -; CHECK-NEXT: [[TMP60:%.*]] = select i1 [[OR_COND_5]], i32 [[TMP54]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP61:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[DOTNEG53]] ; CHECK-NEXT: [[TMP62:%.*]] = load i32, ptr [[TMP61]], align 4 ; CHECK-NEXT: [[TMP63:%.*]] = icmp ne i32 [[TMP62]], [[TMP20]] ; CHECK-NEXT: [[TMP64:%.*]] = icmp sge i32 [[TMP62]], [[TMP60]] ; CHECK-NEXT: [[DOTNOT33_6:%.*]] = and i1 [[DOT2_5]], [[TMP64]] ; CHECK-NEXT: [[OR_COND_6:%.*]] = select i1 [[TMP63]], i1 true, i1 [[DOTNOT33_6]] -; CHECK-NEXT: [[TMP65:%.*]] = select i1 [[OR_COND_6]], i32 [[TMP59]], i32 7 +; CHECK-NEXT: [[OR_COND_6_FROZEN:%.*]] = freeze i1 [[OR_COND_6]] +; CHECK-NEXT: br i1 [[OR_COND_6_FROZEN]], label [[SELECT_END11:%.*]], label [[SELECT_FALSE12:%.*]] +; CHECK: select.false12: +; CHECK-NEXT: br label [[SELECT_END11]] +; CHECK: select.end11: +; CHECK-NEXT: [[TMP65:%.*]] = phi i32 [ [[TMP59]], [[SELECT_END9]] ], [ 7, [[SELECT_FALSE12]] ] +; CHECK-NEXT: [[DOT2_6:%.*]] = phi i1 [ [[DOT2_5]], [[SELECT_END9]] ], [ true, [[SELECT_FALSE12]] ] +; CHECK-NEXT: [[TMP66:%.*]] = phi i32 [ [[TMP60]], [[SELECT_END9]] ], [ [[TMP20]], [[SELECT_FALSE12]] ] ; CHECK-NEXT: [[NOT_OR_COND_6:%.*]] = xor i1 [[OR_COND_6]], true -; CHECK-NEXT: [[DOT2_6:%.*]] = select i1 [[NOT_OR_COND_6]], i1 true, i1 [[DOT2_5]] -; CHECK-NEXT: [[TMP66:%.*]] = select i1 [[OR_COND_6]], i32 [[TMP60]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP67:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[DOTNEG54]] ; CHECK-NEXT: [[TMP68:%.*]] = load i32, ptr [[TMP67]], align 4 ; CHECK-NEXT: [[TMP69:%.*]] = icmp ne i32 [[TMP68]], [[TMP20]] ; CHECK-NEXT: [[TMP70:%.*]] = icmp sge i32 [[TMP68]], [[TMP66]] ; CHECK-NEXT: [[DOTNOT33_7:%.*]] = and i1 [[DOT2_6]], [[TMP70]] ; CHECK-NEXT: [[OR_COND_7:%.*]] = select i1 [[TMP69]], i1 true, i1 [[DOTNOT33_7]] -; CHECK-NEXT: [[TMP71:%.*]] = select i1 [[OR_COND_7]], i32 [[TMP65]], i32 8 +; CHECK-NEXT: [[OR_COND_7_FROZEN:%.*]] = freeze i1 [[OR_COND_7]] +; CHECK-NEXT: br i1 [[OR_COND_7_FROZEN]], label [[SELECT_END13:%.*]], label [[SELECT_FALSE14:%.*]] +; CHECK: select.false14: +; CHECK-NEXT: br label [[SELECT_END13]] +; CHECK: select.end13: +; CHECK-NEXT: [[TMP71:%.*]] = phi i32 [ [[TMP65]], [[SELECT_END11]] ], [ 8, [[SELECT_FALSE14]] ] +; CHECK-NEXT: [[DOT2_7:%.*]] = phi i1 [ [[DOT2_6]], [[SELECT_END11]] ], [ true, [[SELECT_FALSE14]] ] +; CHECK-NEXT: [[TMP72:%.*]] = phi i32 [ [[TMP66]], [[SELECT_END11]] ], [ [[TMP20]], [[SELECT_FALSE14]] ] ; CHECK-NEXT: [[NOT_OR_COND_7:%.*]] = xor i1 [[OR_COND_7]], true -; CHECK-NEXT: [[DOT2_7:%.*]] = select i1 [[NOT_OR_COND_7]], i1 true, i1 [[DOT2_6]] -; CHECK-NEXT: [[TMP72:%.*]] = select i1 [[OR_COND_7]], i32 [[TMP66]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP73:%.*]] = getelementptr i8, ptr [[TMP25]], i64 [[DOTNEG55]] ; CHECK-NEXT: [[TMP74:%.*]] = load i32, ptr [[TMP73]], align 4 ; CHECK-NEXT: [[TMP75:%.*]] = icmp ne i32 [[TMP74]], [[TMP20]] ; CHECK-NEXT: [[TMP76:%.*]] = icmp sge i32 [[TMP74]], [[TMP72]] ; CHECK-NEXT: [[DOTNOT33_8:%.*]] = and i1 [[DOT2_7]], [[TMP76]] ; CHECK-NEXT: [[OR_COND_8:%.*]] = select i1 [[TMP75]], i1 true, i1 [[DOTNOT33_8]] -; CHECK-NEXT: [[TMP77]] = select i1 [[OR_COND_8]], i32 [[TMP71]], i32 9 +; CHECK-NEXT: [[OR_COND_8_FROZEN:%.*]] = freeze i1 [[OR_COND_8]] +; CHECK-NEXT: br i1 [[OR_COND_8_FROZEN]], label [[SELECT_END15]], label [[SELECT_FALSE16:%.*]] +; CHECK: select.false16: +; CHECK-NEXT: br label [[SELECT_END15]] +; CHECK: select.end15: +; CHECK-NEXT: [[TMP77]] = phi i32 [ [[TMP71]], [[SELECT_END13]] ], [ 9, [[SELECT_FALSE16]] ] +; CHECK-NEXT: [[DOT2_8]] = phi i1 [ [[DOT2_7]], [[SELECT_END13]] ], [ true, [[SELECT_FALSE16]] ] +; CHECK-NEXT: [[TMP78]] = phi i32 [ [[TMP72]], [[SELECT_END13]] ], [ [[TMP20]], [[SELECT_FALSE16]] ] ; CHECK-NEXT: [[NOT_OR_COND_8:%.*]] = xor i1 [[OR_COND_8]], true -; CHECK-NEXT: [[DOT2_8]] = select i1 [[NOT_OR_COND_8]], i1 true, i1 [[DOT2_7]] -; CHECK-NEXT: [[TMP78]] = select i1 [[OR_COND_8]], i32 [[TMP72]], i32 [[TMP20]] ; CHECK-NEXT: [[TMP79]] = add nuw nsw i64 [[TMP23]], 1 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[TMP79]], [[TMP9]] ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[DOTPREHEADER]], label [[DOTPREHEADER35]] ; CHECK: .preheader: -; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP77]], [[DOTPREHEADER35]] ] +; CHECK-NEXT: [[DOTLCSSA3641_LCSSA:%.*]] = phi i32 [ 0, [[TMP3:%.*]] ], [ [[TMP77]], [[SELECT_END15]] ] ; CHECK-NEXT: ret i32 [[DOTLCSSA3641_LCSSA]] ; %4 = getelementptr i8, ptr %0, i64 40