diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5283,6 +5283,47 @@ return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second); } +/// If we have a comparison with a non-canonical predicate, if we can update +/// all the users, invert the predicate and adjust all the users. +static CmpInst *canonicalizeICmpPredicate(CmpInst &I) { + // Is the predicate already canonical? + CmpInst::Predicate Pred = I.getPredicate(); + if (isCanonicalPredicate(Pred)) + return nullptr; + + // Can all users be adjusted to predicate inversion? + if (!canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr)) + return nullptr; + + // Ok, we can canonicalize comparison! + // Let's first invert the comparison's predicate. + I.setPredicate(CmpInst::getInversePredicate(Pred)); + I.setName(I.getName() + ".not"); + + // And now let's adjust every user. + for (User *U : I.users()) { + switch (cast(U)->getOpcode()) { + case Instruction::Select: { + auto *SI = cast(U); + SI->swapValues(); + SI->swapProfMetadata(); + break; + } + case Instruction::Br: + cast(U)->swapSuccessors(); // swaps prof metadata too + break; + case Instruction::Xor: + U->replaceAllUsesWith(&I); + break; + default: + llvm_unreachable("Got unexpected user - out of sync with " + "canFreelyInvertAllUsersOf() ?"); + } + } + + return &I; +} + /// Integer compare with boolean values can always be turned into bitwise ops. static Instruction *canonicalizeICmpBool(ICmpInst &I, InstCombiner::BuilderTy &Builder) { @@ -5521,8 +5562,11 @@ if (Instruction *Res = canonicalizeICmpBool(I, Builder)) return Res; - if (ICmpInst *NewICmp = canonicalizeCmpWithConstant(I)) - return NewICmp; + if (Instruction *Res = canonicalizeCmpWithConstant(I)) + return Res; + + if (Instruction *Res = canonicalizeICmpPredicate(I)) + return Res; if (Instruction *Res = foldICmpWithConstant(I)) return Res; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -219,14 +219,18 @@ /// See also: isFreeToInvert() static inline bool canFreelyInvertAllUsersOf(Value *V, Value *IgnoredUser) { // Look at every user of V. - for (User *U : V->users()) { - if (U == IgnoredUser) + for (Use &U : V->uses()) { + if (U.getUser() == IgnoredUser) continue; // Don't consider this user. - auto *I = cast(U); + auto *I = cast(U.getUser()); switch (I->getOpcode()) { case Instruction::Select: + if (U.getOperandNo() != 0) // Only if the value is used as select cond. + return false; + break; case Instruction::Br: + assert(U.getOperandNo() == 0 && "Must be branching on that value."); break; // Free to invert by swapping true/false values/destinations. case Instruction::Xor: // Can invert 'xor' if it's a 'not', by ignoring it. if (!match(I, m_Not(m_Value()))) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2532,21 +2532,7 @@ if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this)) return I; - // Canonicalize a one-use integer compare with a non-canonical predicate by - // inverting the predicate and swapping the select operands. This matches a - // compare canonicalization for conditional branches. - // TODO: Should we do the same for FP compares? CmpInst::Predicate Pred; - if (match(CondVal, m_OneUse(m_ICmp(Pred, m_Value(), m_Value()))) && - !isCanonicalPredicate(Pred)) { - // Swap true/false values and condition. - CmpInst *Cond = cast(CondVal); - Cond->setPredicate(CmpInst::getInversePredicate(Pred)); - SI.swapValues(); - SI.swapProfMetadata(); - Worklist.push(Cond); - return &SI; - } if (SelType->isIntOrIntVectorTy(1) && TrueVal->getType() == CondVal->getType()) { diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2755,9 +2755,9 @@ return replaceOperand( BI, 0, ConstantInt::getFalse(BI.getCondition()->getType())); - // Canonicalize, for example, icmp_ne -> icmp_eq or fcmp_one -> fcmp_oeq. + // Canonicalize, for example, fcmp_one -> fcmp_oeq. CmpInst::Predicate Pred; - if (match(&BI, m_Br(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())), + if (match(&BI, m_Br(m_OneUse(m_FCmp(Pred, m_Value(), m_Value())), m_BasicBlock(), m_BasicBlock())) && !isCanonicalPredicate(Pred)) { // Swap destinations and condition. diff --git a/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll b/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll --- a/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll +++ b/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll @@ -8,8 +8,8 @@ define i8 @p0(i8 %x, i8 %v0, i8 %v1) { ; CHECK-LABEL: @p0( ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0 -; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0 +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 +; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0 ; CHECK-NEXT: ret i8 [[R]] ; %t0 = and i8 %x, 1 @@ -20,8 +20,8 @@ define i8 @p1(i8 %x, i8 %v0, i8 %v1) { ; CHECK-LABEL: @p1( ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0 -; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]] +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 +; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] ; CHECK-NEXT: ret i8 [[R]] ; %t0 = and i8 %x, 1 @@ -51,14 +51,14 @@ ; CHECK-LABEL: @t3( ; CHECK-NEXT: bb0: ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0 +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: -; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]] +; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] ; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1 ; CHECK-NEXT: br label [[BB2]] ; CHECK: bb2: -; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]] +; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]] ; CHECK-NEXT: ret i8 [[R1]] ; bb0: @@ -76,10 +76,10 @@ define i8 @t4(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out) { ; CHECK-LABEL: @t4( ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0 -; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]] +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 +; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] ; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1 -; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]] +; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]] ; CHECK-NEXT: ret i8 [[R1]] ; %t0 = and i8 %x, 1 @@ -112,8 +112,8 @@ define i8 @n7(i8 %x, i8 %v0, i8 %v1) { ; CHECK-LABEL: @n7( ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0 -; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]] +; CHECK-NEXT: [[T1_NOT_NOT:%.*]] = icmp eq i8 [[T0]], 0 +; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT_NOT]], i8 [[V0:%.*]], i8 [[V1:%.*]] ; CHECK-NEXT: ret i8 [[R]] ; %t0 = and i8 %x, 1 diff --git a/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll b/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll --- a/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll +++ b/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll @@ -13,13 +13,13 @@ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], [[SH_PROM]] ; CHECK-NEXT: [[CONV2:%.*]] = zext i32 [[SHR]] to i64 ; CHECK-NEXT: [[MUL3:%.*]] = mul nuw nsw i64 [[CONV]], [[CONV2]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i64 [[MUL3]], 4294967295 -; CHECK-NEXT: br i1 [[TMP3]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[MUL3]], 4294967296 +; CHECK-NEXT: br i1 [[TMP3]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]] ; CHECK: lor.rhs: ; CHECK-NEXT: [[AND:%.*]] = and i64 [[MUL3]], [[TMP2]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i64 [[AND]] to i32 -; CHECK-NEXT: [[TOBOOL7:%.*]] = icmp eq i32 [[CONV4]], 0 -; CHECK-NEXT: [[PHITMP:%.*]] = zext i1 [[TOBOOL7]] to i32 +; CHECK-NEXT: [[TOBOOL7_NOT:%.*]] = icmp eq i32 [[CONV4]], 0 +; CHECK-NEXT: [[PHITMP:%.*]] = zext i1 [[TOBOOL7_NOT]] to i32 ; CHECK-NEXT: br label [[LOR_END]] ; CHECK: lor.end: ; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHITMP]], [[LOR_RHS]] ] diff --git a/llvm/test/Transforms/InstCombine/logical-select.ll b/llvm/test/Transforms/InstCombine/logical-select.ll --- a/llvm/test/Transforms/InstCombine/logical-select.ll +++ b/llvm/test/Transforms/InstCombine/logical-select.ll @@ -19,8 +19,8 @@ define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-LABEL: @bar( -; CHECK-NEXT: [[E:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[E]], i32 [[C:%.*]], i32 [[D:%.*]] +; CHECK-NEXT: [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]] ; CHECK-NEXT: ret i32 [[TMP1]] ; %e = icmp slt i32 %a, %b @@ -69,8 +69,8 @@ ; CHECK-LABEL: @fold_inverted_icmp_preds( ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0 -; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] -; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 0, i32 [[D:%.*]] +; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]] +; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 0, i32 [[D:%.*]] ; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]] ; CHECK-NEXT: ret i32 [[OR]] ; @@ -88,8 +88,8 @@ ; CHECK-LABEL: @fold_inverted_icmp_preds_reverse( ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 [[C:%.*]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] -; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 [[D:%.*]], i32 0 +; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]] +; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 [[D:%.*]], i32 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]] ; CHECK-NEXT: ret i32 [[OR]] ; @@ -124,8 +124,8 @@ define <2 x i32> @fold_inverted_icmp_vector_preds(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d) { ; CHECK-LABEL: @fold_inverted_icmp_vector_preds( -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]] +; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]] ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[A]], [[B]] ; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[D:%.*]], <2 x i32> zeroinitializer ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SEL1]], [[SEL2]] @@ -535,9 +535,9 @@ define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) { ; CHECK-LABEL: @allSignBits( -; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[COND:%.*]], -1 -; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[FVAL:%.*]], i32 [[TVAL:%.*]] -; CHECK-NEXT: ret i32 [[TMP2]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp slt i32 [[COND:%.*]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTNOT]], i32 [[TVAL:%.*]], i32 [[FVAL:%.*]] +; CHECK-NEXT: ret i32 [[TMP1]] ; %bitmask = ashr i32 %cond, 31 %not_bitmask = xor i32 %bitmask, -1 @@ -549,9 +549,9 @@ define <4 x i8> @allSignBits_vec(<4 x i8> %cond, <4 x i8> %tval, <4 x i8> %fval) { ; CHECK-LABEL: @allSignBits_vec( -; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i8> [[COND:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> [[FVAL:%.*]], <4 x i8> [[TVAL:%.*]] -; CHECK-NEXT: ret <4 x i8> [[TMP2]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp sgt <4 x i8> [[COND:%.*]], +; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[DOTNOT]], <4 x i8> [[FVAL:%.*]], <4 x i8> [[TVAL:%.*]] +; CHECK-NEXT: ret <4 x i8> [[TMP1]] ; %bitmask = ashr <4 x i8> %cond, %not_bitmask = xor <4 x i8> %bitmask, diff --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll --- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll +++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll @@ -153,9 +153,9 @@ define i32 @select_icmp_ne_0_and_4096_xor_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_xor_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -168,9 +168,9 @@ define i32 @select_icmp_ne_0_and_4096_and_not_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_and_not_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -311,9 +311,9 @@ define i32 @select_icmp_ne_0_and_4096_xor_32(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_xor_32( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 32 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -326,9 +326,9 @@ define i32 @select_icmp_ne_0_and_4096_and_not_32(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_and_not_32( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -33 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -371,9 +371,9 @@ define i32 @select_icmp_ne_0_and_32_xor_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_32_xor_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 32 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 32 @@ -386,9 +386,9 @@ define i32 @select_icmp_ne_0_and_32_and_not_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_32_and_not_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 32 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 32 @@ -401,9 +401,9 @@ define i8 @select_icmp_ne_0_and_1073741824_or_8(i32 %x, i8 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_1073741824_or_8( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1073741824 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], 8 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i8 [[OR]], i8 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i8 [[OR]], i8 [[Y]] ; CHECK-NEXT: ret i8 [[SELECT]] ; %and = and i32 %x, 1073741824 @@ -416,9 +416,9 @@ define i8 @select_icmp_ne_0_and_1073741824_xor_8(i32 %x, i8 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_1073741824_xor_8( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1073741824 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y:%.*]], 8 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i8 [[XOR]], i8 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i8 [[XOR]], i8 [[Y]] ; CHECK-NEXT: ret i8 [[SELECT]] ; %and = and i32 %x, 1073741824 @@ -431,9 +431,9 @@ define i8 @select_icmp_ne_0_and_1073741824_and_not_8(i32 %x, i8 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_1073741824_and_not_8( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1073741824 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i8 [[Y:%.*]], -9 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i8 [[AND2]], i8 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i8 [[AND2]], i8 [[Y]] ; CHECK-NEXT: ret i8 [[SELECT]] ; %and = and i32 %x, 1073741824 @@ -446,9 +446,9 @@ define i32 @select_icmp_ne_0_and_8_or_1073741824(i8 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_8_or_1073741824( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 1073741824 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i8 %x, 8 @@ -461,9 +461,9 @@ define i32 @select_icmp_ne_0_and_8_xor_1073741824(i8 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_8_xor_1073741824( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 1073741824 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i8 %x, 8 @@ -476,9 +476,9 @@ define i32 @select_icmp_ne_0_and_8_and_not_1073741824(i8 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_8_and_not_1073741824( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -1073741825 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i8 %x, 8 @@ -731,9 +731,9 @@ define i32 @test69_xor(i32 %x, i32 %y) { ; CHECK-LABEL: @test69_xor( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i8 [[TMP1]], -1 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 128 @@ -746,9 +746,9 @@ define i32 @test69_and(i32 %x, i32 %y) { ; CHECK-LABEL: @test69_and( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i8 [[TMP1]], -1 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], 2 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 128 @@ -892,9 +892,9 @@ define i32 @no_shift_xor_multiuse_xor(i32 %x, i32 %y) { ; CHECK-LABEL: @no_shift_xor_multiuse_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -909,9 +909,9 @@ define i32 @no_shift_xor_multiuse_and(i32 %x, i32 %y) { ; CHECK-LABEL: @no_shift_xor_multiuse_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -926,9 +926,9 @@ define i32 @shift_xor_multiuse_or(i32 %x, i32 %y) { ; CHECK-LABEL: @shift_xor_multiuse_or( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[OR]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -943,9 +943,9 @@ define i32 @shift_xor_multiuse_xor(i32 %x, i32 %y) { ; CHECK-LABEL: @shift_xor_multiuse_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -960,9 +960,9 @@ define i32 @shift_xor_multiuse_and(i32 %x, i32 %y) { ; CHECK-LABEL: @shift_xor_multiuse_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -2049 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1090,10 +1090,10 @@ define i32 @no_shift_xor_multiuse_cmp(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[AND]], 4096 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[Y:%.*]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[W:%.*]], i32 [[Z:%.*]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[TMP2]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1109,10 +1109,10 @@ define i32 @no_shift_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_with_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1128,10 +1128,10 @@ define i32 @no_shift_xor_multiuse_cmp_with_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_with_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1147,10 +1147,10 @@ define i32 @shift_xor_multiuse_cmp(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1166,10 +1166,10 @@ define i32 @shift_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_with_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1185,10 +1185,10 @@ define i32 @shift_xor_multiuse_cmp_with_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_with_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -2049 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1330,10 +1330,10 @@ define i32 @no_shift_xor_multiuse_cmp_or(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_or( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[OR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1351,10 +1351,10 @@ define i32 @no_shift_xor_multiuse_cmp_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1372,10 +1372,10 @@ define i32 @no_shift_xor_multiuse_cmp_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1393,10 +1393,10 @@ define i32 @shift_xor_multiuse_cmp_or(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_or( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[OR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1414,10 +1414,10 @@ define i32 @shift_xor_multiuse_cmp_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1435,10 +1435,10 @@ define i32 @shift_xor_multiuse_cmp_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES2]] diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll --- a/llvm/test/Transforms/InstCombine/shift.ll +++ b/llvm/test/Transforms/InstCombine/shift.ll @@ -428,8 +428,8 @@ ; CHECK-LABEL: @test28a( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[I1:%.*]] = lshr i8 [[X:%.*]], 7 -; CHECK-NEXT: [[COND1:%.*]] = icmp slt i8 [[X]], 0 -; CHECK-NEXT: br i1 [[COND1]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK-NEXT: [[COND1_NOT:%.*]] = icmp sgt i8 [[X]], -1 +; CHECK-NEXT: br i1 [[COND1_NOT]], label [[BB2:%.*]], label [[BB1:%.*]] ; CHECK: bb1: ; CHECK-NEXT: ret i8 [[I1]] ; CHECK: bb2: diff --git a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll --- a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll +++ b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-loop-lcssa -verify-dom-info -verify-loop-info -S | FileCheck %s -check-prefix=EPILOG-NO-IC ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-loop-lcssa -verify-dom-info -verify-loop-info -instcombine -S | FileCheck %s -check-prefix=EPILOG ; RUN: opt < %s -loop-unroll -unroll-runtime -unroll-count=2 -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-loop-lcssa -verify-dom-info -verify-loop-info -instcombine @@ -12,43 +13,321 @@ ; test with three exiting and three exit blocks. ; none of the exit blocks have successors define void @test1(i64 %trip, i1 %cond) { -; EPILOG: test1( +; EPILOG-NO-IC-LABEL: @test1( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 +; EPILOG-NO-IC-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 +; EPILOG-NO-IC-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; EPILOG-NO-IC-NEXT: br i1 [[TMP1]], label [[EXIT2_LOOPEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] +; EPILOG-NO-IC: entry.new: +; EPILOG-NO-IC-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[TRIP]], [[XTRAITER]] +; EPILOG-NO-IC-NEXT: br label [[LOOP_HEADER:%.*]] +; EPILOG-NO-IC: loop_header: +; EPILOG-NO-IC-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_7:%.*]], [[LOOP_LATCH_7:%.*]] ] +; EPILOG-NO-IC-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LOOP_LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br i1 [[COND:%.*]], label [[LOOP_LATCH:%.*]], label [[LOOP_EXITING_BB1:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2:%.*]], label [[EXIT1_LOOPEXIT:%.*]] +; EPILOG-NO-IC: loop_exiting_bb2: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH]], label [[EXIT3_LOOPEXIT:%.*]] +; EPILOG-NO-IC: exit3.loopexit: +; EPILOG-NO-IC-NEXT: br label [[EXIT3:%.*]] +; EPILOG-NO-IC: exit3.loopexit2: +; EPILOG-NO-IC-NEXT: br label [[EXIT3]] +; EPILOG-NO-IC: exit3: +; EPILOG-NO-IC-NEXT: ret void +; EPILOG-NO-IC: loop_latch: +; EPILOG-NO-IC-NEXT: [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB:%.*]] = sub i64 [[NITER]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_1:%.*]], label [[LOOP_EXITING_BB1_1:%.*]] +; EPILOG-NO-IC: exit1.loopexit: +; EPILOG-NO-IC-NEXT: br label [[EXIT1:%.*]] +; EPILOG-NO-IC: exit1.loopexit1: +; EPILOG-NO-IC-NEXT: br label [[EXIT1]] +; EPILOG-NO-IC: exit1: +; EPILOG-NO-IC-NEXT: ret void +; EPILOG-NO-IC: exit2.loopexit.unr-lcssa.loopexit: +; EPILOG-NO-IC-NEXT: [[IV_UNR_PH:%.*]] = phi i64 [ [[IV_NEXT_7]], [[LOOP_LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br label [[EXIT2_LOOPEXIT_UNR_LCSSA]] +; EPILOG-NO-IC: exit2.loopexit.unr-lcssa: +; EPILOG-NO-IC-NEXT: [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NO-IC-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[LCMP_MOD]], label [[LOOP_HEADER_EPIL_PREHEADER:%.*]], label [[EXIT2_LOOPEXIT:%.*]] +; EPILOG-NO-IC: loop_header.epil.preheader: +; EPILOG-NO-IC-NEXT: br label [[LOOP_HEADER_EPIL:%.*]] +; EPILOG-NO-IC: loop_header.epil: +; EPILOG-NO-IC-NEXT: [[IV_EPIL:%.*]] = phi i64 [ [[IV_UNR]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[IV_NEXT_EPIL:%.*]], [[LOOP_LATCH_EPIL:%.*]] ] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[LOOP_LATCH_EPIL]] ] +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_EPIL]], label [[LOOP_EXITING_BB1_EPIL:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.epil: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_EPIL:%.*]], label [[EXIT1_LOOPEXIT1:%.*]] +; EPILOG-NO-IC: loop_exiting_bb2.epil: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_EPIL]], label [[EXIT3_LOOPEXIT2:%.*]] +; EPILOG-NO-IC: loop_latch.epil: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_EPIL]] = add i64 [[IV_EPIL]], 1 +; EPILOG-NO-IC-NEXT: [[CMP_EPIL:%.*]] = icmp ne i64 [[IV_NEXT_EPIL]], [[TRIP]] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_SUB]] = sub i64 [[EPIL_ITER]], 1 +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[EPIL_ITER_CMP]], label [[LOOP_HEADER_EPIL]], label [[EXIT2_LOOPEXIT_EPILOG_LCSSA:%.*]], !llvm.loop !0 +; EPILOG-NO-IC: exit2.loopexit.epilog-lcssa: +; EPILOG-NO-IC-NEXT: br label [[EXIT2_LOOPEXIT]] +; EPILOG-NO-IC: exit2.loopexit: +; EPILOG-NO-IC-NEXT: ret void +; EPILOG-NO-IC: loop_exiting_bb1.1: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_1:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC: loop_exiting_bb2.1: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_1]], label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC: loop_latch.1: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV_NEXT]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_1:%.*]] = sub i64 [[NITER_NSUB]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_2:%.*]], label [[LOOP_EXITING_BB1_2:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.2: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_2:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC: loop_exiting_bb2.2: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_2]], label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC: loop_latch.2: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV_NEXT_1]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_2:%.*]] = sub i64 [[NITER_NSUB_1]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_3:%.*]], label [[LOOP_EXITING_BB1_3:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.3: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_3:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC: loop_exiting_bb2.3: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_3]], label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC: loop_latch.3: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_3:%.*]] = add nuw nsw i64 [[IV_NEXT_2]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_3:%.*]] = sub i64 [[NITER_NSUB_2]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_4:%.*]], label [[LOOP_EXITING_BB1_4:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.4: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_4:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC: loop_exiting_bb2.4: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_4]], label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC: loop_latch.4: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_4:%.*]] = add nuw nsw i64 [[IV_NEXT_3]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_4:%.*]] = sub i64 [[NITER_NSUB_3]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_5:%.*]], label [[LOOP_EXITING_BB1_5:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.5: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_5:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC: loop_exiting_bb2.5: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_5]], label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC: loop_latch.5: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_5:%.*]] = add nuw nsw i64 [[IV_NEXT_4]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_5:%.*]] = sub i64 [[NITER_NSUB_4]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_6:%.*]], label [[LOOP_EXITING_BB1_6:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.6: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_6:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC: loop_exiting_bb2.6: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_6]], label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC: loop_latch.6: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_6:%.*]] = add nuw nsw i64 [[IV_NEXT_5]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_6:%.*]] = sub i64 [[NITER_NSUB_5]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[COND]], label [[LOOP_LATCH_7]], label [[LOOP_EXITING_BB1_7:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.7: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_EXITING_BB2_7:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC: loop_exiting_bb2.7: +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOP_LATCH_7]], label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC: loop_latch.7: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_7]] = add i64 [[IV_NEXT_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_7]] = sub i64 [[NITER_NSUB_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NCMP_7:%.*]] = icmp ne i64 [[NITER_NSUB_7]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[NITER_NCMP_7]], label [[LOOP_HEADER]], label [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] +; +; EPILOG-LABEL: @test1( ; EPILOG-NEXT: entry: ; EPILOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 ; EPILOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 ; EPILOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 -; EPILOG-NEXT: br i1 [[TMP1]], label %exit2.loopexit.unr-lcssa, label [[ENTRY_NEW:%.*]] +; EPILOG-NEXT: br i1 [[TMP1]], label [[EXIT2_LOOPEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] ; EPILOG: entry.new: ; EPILOG-NEXT: [[UNROLL_ITER:%.*]] = and i64 [[TRIP]], -8 ; EPILOG-NEXT: br label [[LOOP_HEADER:%.*]] -; EPILOG: loop_latch.epil: -; EPILOG-NEXT: %epil.iter.sub = add i64 %epil.iter, -1 -; EPILOG-NEXT: %epil.iter.cmp = icmp eq i64 %epil.iter.sub, 0 -; EPILOG-NEXT: br i1 %epil.iter.cmp, label %exit2.loopexit.epilog-lcssa, label %loop_header.epil -; EPILOG: loop_latch.7: -; EPILOG-NEXT: %niter.nsub.7 = add i64 %niter, -8 -; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.nsub.7, 0 -; EPILOG-NEXT: br i1 %niter.ncmp.7, label %exit2.loopexit.unr-lcssa.loopexit, label %loop_header - -; PROLOG: test1( +; EPILOG: loop_header: +; EPILOG-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LOOP_LATCH_7:%.*]] ] +; EPILOG-NEXT: br i1 [[COND:%.*]], label [[LOOP_LATCH:%.*]], label [[LOOP_EXITING_BB1:%.*]] +; EPILOG: loop_exiting_bb1: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2:%.*]], label [[EXIT1_LOOPEXIT:%.*]] +; EPILOG: loop_exiting_bb2: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH]], label [[EXIT3_LOOPEXIT:%.*]] +; EPILOG: exit3.loopexit: +; EPILOG-NEXT: br label [[EXIT3:%.*]] +; EPILOG: exit3.loopexit2: +; EPILOG-NEXT: br label [[EXIT3]] +; EPILOG: exit3: +; EPILOG-NEXT: ret void +; EPILOG: loop_latch: +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_1:%.*]], label [[LOOP_EXITING_BB1_1:%.*]] +; EPILOG: exit1.loopexit: +; EPILOG-NEXT: br label [[EXIT1:%.*]] +; EPILOG: exit1.loopexit1: +; EPILOG-NEXT: br label [[EXIT1]] +; EPILOG: exit1: +; EPILOG-NEXT: ret void +; EPILOG: exit2.loopexit.unr-lcssa.loopexit: +; EPILOG-NEXT: br label [[EXIT2_LOOPEXIT_UNR_LCSSA]] +; EPILOG: exit2.loopexit.unr-lcssa: +; EPILOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; EPILOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[EXIT2_LOOPEXIT:%.*]], label [[LOOP_HEADER_EPIL_PREHEADER:%.*]] +; EPILOG: loop_header.epil.preheader: +; EPILOG-NEXT: br label [[LOOP_HEADER_EPIL:%.*]] +; EPILOG: loop_header.epil: +; EPILOG-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[LOOP_LATCH_EPIL:%.*]] ] +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_EPIL]], label [[LOOP_EXITING_BB1_EPIL:%.*]] +; EPILOG: loop_exiting_bb1.epil: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_EPIL:%.*]], label [[EXIT1_LOOPEXIT1:%.*]] +; EPILOG: loop_exiting_bb2.epil: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_EPIL]], label [[EXIT3_LOOPEXIT2:%.*]] +; EPILOG: loop_latch.epil: +; EPILOG-NEXT: [[EPIL_ITER_SUB]] = add i64 [[EPIL_ITER]], -1 +; EPILOG-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[EXIT2_LOOPEXIT_EPILOG_LCSSA:%.*]], label [[LOOP_HEADER_EPIL]], !llvm.loop !0 +; EPILOG: exit2.loopexit.epilog-lcssa: +; EPILOG-NEXT: br label [[EXIT2_LOOPEXIT]] +; EPILOG: exit2.loopexit: +; EPILOG-NEXT: ret void +; EPILOG: loop_exiting_bb1.1: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_1:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG: loop_exiting_bb2.1: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_1]], label [[EXIT3_LOOPEXIT]] +; EPILOG: loop_latch.1: +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_2:%.*]], label [[LOOP_EXITING_BB1_2:%.*]] +; EPILOG: loop_exiting_bb1.2: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_2:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG: loop_exiting_bb2.2: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_2]], label [[EXIT3_LOOPEXIT]] +; EPILOG: loop_latch.2: +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_3:%.*]], label [[LOOP_EXITING_BB1_3:%.*]] +; EPILOG: loop_exiting_bb1.3: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_3:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG: loop_exiting_bb2.3: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_3]], label [[EXIT3_LOOPEXIT]] +; EPILOG: loop_latch.3: +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_4:%.*]], label [[LOOP_EXITING_BB1_4:%.*]] +; EPILOG: loop_exiting_bb1.4: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_4:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG: loop_exiting_bb2.4: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_4]], label [[EXIT3_LOOPEXIT]] +; EPILOG: loop_latch.4: +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_5:%.*]], label [[LOOP_EXITING_BB1_5:%.*]] +; EPILOG: loop_exiting_bb1.5: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_5:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG: loop_exiting_bb2.5: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_5]], label [[EXIT3_LOOPEXIT]] +; EPILOG: loop_latch.5: +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_6:%.*]], label [[LOOP_EXITING_BB1_6:%.*]] +; EPILOG: loop_exiting_bb1.6: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_6:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG: loop_exiting_bb2.6: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_6]], label [[EXIT3_LOOPEXIT]] +; EPILOG: loop_latch.6: +; EPILOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_7]], label [[LOOP_EXITING_BB1_7:%.*]] +; EPILOG: loop_exiting_bb1.7: +; EPILOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_7:%.*]], label [[EXIT1_LOOPEXIT]] +; EPILOG: loop_exiting_bb2.7: +; EPILOG-NEXT: br i1 false, label [[LOOP_LATCH_7]], label [[EXIT3_LOOPEXIT]] +; EPILOG: loop_latch.7: +; EPILOG-NEXT: [[NITER_NSUB_7]] = add i64 [[NITER]], -8 +; EPILOG-NEXT: [[NITER_NCMP_7_NOT:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0 +; EPILOG-NEXT: br i1 [[NITER_NCMP_7_NOT]], label [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[LOOP_HEADER]] +; +; PROLOG-LABEL: @test1( ; PROLOG-NEXT: entry: ; PROLOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 ; PROLOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 -; PROLOG-NEXT: [[TMP1:%.*]] = icmp eq i64 [[XTRAITER]], 0 -; PROLOG-NEXT: br i1 [[TMP1]], label %loop_header.prol.loopexit, label %loop_header.prol.preheader +; PROLOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; PROLOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[LOOP_HEADER_PROL_LOOPEXIT:%.*]], label [[LOOP_HEADER_PROL_PREHEADER:%.*]] +; PROLOG: loop_header.prol.preheader: +; PROLOG-NEXT: br label [[LOOP_HEADER_PROL:%.*]] ; PROLOG: loop_header.prol: -; PROLOG-NEXT: %iv.prol = phi i64 [ 0, %loop_header.prol.preheader ], [ %iv_next.prol, %loop_latch.prol ] -; PROLOG-NEXT: %prol.iter = phi i64 [ [[XTRAITER]], %loop_header.prol.preheader ], [ %prol.iter.sub, %loop_latch.prol ] -; PROLOG-NEXT: br i1 %cond, label %loop_latch.prol, label %loop_exiting_bb1.prol +; PROLOG-NEXT: [[IV_PROL:%.*]] = phi i64 [ 0, [[LOOP_HEADER_PROL_PREHEADER]] ], [ [[IV_NEXT_PROL:%.*]], [[LOOP_LATCH_PROL:%.*]] ] +; PROLOG-NEXT: [[PROL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[LOOP_HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_SUB:%.*]], [[LOOP_LATCH_PROL]] ] +; PROLOG-NEXT: br i1 [[COND:%.*]], label [[LOOP_LATCH_PROL]], label [[LOOP_EXITING_BB1_PROL:%.*]] +; PROLOG: loop_exiting_bb1.prol: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_PROL:%.*]], label [[EXIT1_LOOPEXIT1:%.*]] +; PROLOG: loop_exiting_bb2.prol: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_PROL]], label [[EXIT3_LOOPEXIT2:%.*]] ; PROLOG: loop_latch.prol: -; PROLOG-NEXT: %iv_next.prol = add i64 %iv.prol, 1 -; PROLOG-NEXT: %prol.iter.sub = add i64 %prol.iter, -1 -; PROLOG-NEXT: %prol.iter.cmp = icmp eq i64 %prol.iter.sub, 0 -; PROLOG-NEXT: br i1 %prol.iter.cmp, label %loop_header.prol.loopexit.unr-lcssa, label %loop_header.prol -; PROLOG: loop_latch.7: -; PROLOG-NEXT: %iv_next.7 = add i64 %iv, 8 -; PROLOG-NEXT: %cmp.7 = icmp eq i64 %iv_next.7, %trip -; PROLOG-NEXT: br i1 %cmp.7, label %exit2.loopexit.unr-lcssa, label %loop_header +; PROLOG-NEXT: [[IV_NEXT_PROL]] = add i64 [[IV_PROL]], 1 +; PROLOG-NEXT: [[PROL_ITER_SUB]] = add i64 [[PROL_ITER]], -1 +; PROLOG-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_SUB]], 0 +; PROLOG-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label [[LOOP_HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], label [[LOOP_HEADER_PROL]], !llvm.loop !0 +; PROLOG: loop_header.prol.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[LOOP_HEADER_PROL_LOOPEXIT]] +; PROLOG: loop_header.prol.loopexit: +; PROLOG-NEXT: [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_PROL]], [[LOOP_HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; PROLOG-NEXT: br i1 [[TMP1]], label [[EXIT2_LOOPEXIT:%.*]], label [[ENTRY_NEW:%.*]] +; PROLOG: entry.new: +; PROLOG-NEXT: br label [[LOOP_HEADER:%.*]] +; PROLOG: loop_header: +; PROLOG-NEXT: [[IV:%.*]] = phi i64 [ [[IV_UNR]], [[ENTRY_NEW]] ], [ [[IV_NEXT_7:%.*]], [[LOOP_LATCH_7:%.*]] ] +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH:%.*]], label [[LOOP_EXITING_BB1:%.*]] +; PROLOG: loop_exiting_bb1: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2:%.*]], label [[EXIT1_LOOPEXIT:%.*]] +; PROLOG: loop_exiting_bb2: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH]], label [[EXIT3_LOOPEXIT:%.*]] +; PROLOG: exit3.loopexit: +; PROLOG-NEXT: br label [[EXIT3:%.*]] +; PROLOG: exit3.loopexit2: +; PROLOG-NEXT: br label [[EXIT3]] +; PROLOG: exit3: +; PROLOG-NEXT: ret void +; PROLOG: loop_latch: +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_1:%.*]], label [[LOOP_EXITING_BB1_1:%.*]] +; PROLOG: exit1.loopexit: +; PROLOG-NEXT: br label [[EXIT1:%.*]] +; PROLOG: exit1.loopexit1: +; PROLOG-NEXT: br label [[EXIT1]] +; PROLOG: exit1: +; PROLOG-NEXT: ret void +; PROLOG: exit2.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[EXIT2_LOOPEXIT]] +; PROLOG: exit2.loopexit: +; PROLOG-NEXT: ret void +; PROLOG: loop_exiting_bb1.1: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_1:%.*]], label [[EXIT1_LOOPEXIT]] +; PROLOG: loop_exiting_bb2.1: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_1]], label [[EXIT3_LOOPEXIT]] +; PROLOG: loop_latch.1: +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_2:%.*]], label [[LOOP_EXITING_BB1_2:%.*]] +; PROLOG: loop_exiting_bb1.2: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_2:%.*]], label [[EXIT1_LOOPEXIT]] +; PROLOG: loop_exiting_bb2.2: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_2]], label [[EXIT3_LOOPEXIT]] +; PROLOG: loop_latch.2: +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_3:%.*]], label [[LOOP_EXITING_BB1_3:%.*]] +; PROLOG: loop_exiting_bb1.3: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_3:%.*]], label [[EXIT1_LOOPEXIT]] +; PROLOG: loop_exiting_bb2.3: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_3]], label [[EXIT3_LOOPEXIT]] +; PROLOG: loop_latch.3: +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_4:%.*]], label [[LOOP_EXITING_BB1_4:%.*]] +; PROLOG: loop_exiting_bb1.4: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_4:%.*]], label [[EXIT1_LOOPEXIT]] +; PROLOG: loop_exiting_bb2.4: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_4]], label [[EXIT3_LOOPEXIT]] +; PROLOG: loop_latch.4: +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_5:%.*]], label [[LOOP_EXITING_BB1_5:%.*]] +; PROLOG: loop_exiting_bb1.5: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_5:%.*]], label [[EXIT1_LOOPEXIT]] +; PROLOG: loop_exiting_bb2.5: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_5]], label [[EXIT3_LOOPEXIT]] +; PROLOG: loop_latch.5: +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_6:%.*]], label [[LOOP_EXITING_BB1_6:%.*]] +; PROLOG: loop_exiting_bb1.6: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_6:%.*]], label [[EXIT1_LOOPEXIT]] +; PROLOG: loop_exiting_bb2.6: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_6]], label [[EXIT3_LOOPEXIT]] +; PROLOG: loop_latch.6: +; PROLOG-NEXT: br i1 [[COND]], label [[LOOP_LATCH_7]], label [[LOOP_EXITING_BB1_7:%.*]] +; PROLOG: loop_exiting_bb1.7: +; PROLOG-NEXT: br i1 false, label [[LOOP_EXITING_BB2_7:%.*]], label [[EXIT1_LOOPEXIT]] +; PROLOG: loop_exiting_bb2.7: +; PROLOG-NEXT: br i1 false, label [[LOOP_LATCH_7]], label [[EXIT3_LOOPEXIT]] +; PROLOG: loop_latch.7: +; PROLOG-NEXT: [[IV_NEXT_7]] = add i64 [[IV]], 8 +; PROLOG-NEXT: [[CMP_7_NOT:%.*]] = icmp eq i64 [[IV_NEXT_7]], [[TRIP]] +; PROLOG-NEXT: br i1 [[CMP_7_NOT]], label [[EXIT2_LOOPEXIT_UNR_LCSSA:%.*]], label [[LOOP_HEADER]] +; + entry: br label %loop_header @@ -71,7 +350,7 @@ br i1 %cmp, label %loop_header, label %exit2.loopexit exit1: - ret void + ret void exit2.loopexit: ret void @@ -84,29 +363,403 @@ ; %sum.02 and %add. Both of these are incoming values for phi from every exiting ; unrolled block. define i32 @test2(i32* nocapture %a, i64 %n) { -; EPILOG: test2( -; EPILOG: for.exit2.loopexit: -; EPILOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %for.body ], [ 42, %for.exiting_block.1 ], [ %add.1, %for.body.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %for.body.2 ], [ 42, %for.exiting_block.3 ], -; EPILOG-NEXT: br label %for.exit2 -; EPILOG: for.exit2.loopexit2: -; EPILOG-NEXT: %retval.ph3 = phi i32 [ 42, %for.exiting_block.epil ], [ %sum.02.epil, %header.epil ] -; EPILOG-NEXT: br label %for.exit2 -; EPILOG: for.exit2: -; EPILOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph3, %for.exit2.loopexit2 ] -; EPILOG-NEXT: ret i32 %retval -; EPILOG: %niter.nsub.7 = add i64 %niter, -8 +; EPILOG-NO-IC-LABEL: @test2( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 +; EPILOG-NO-IC-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 7 +; EPILOG-NO-IC-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; EPILOG-NO-IC-NEXT: br i1 [[TMP1]], label [[FOR_END_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] +; EPILOG-NO-IC: entry.new: +; EPILOG-NO-IC-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]] +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[FOR_BODY_7:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[FOR_BODY_7]] ] +; EPILOG-NO-IC-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[FOR_BODY_7]] ] +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG-NO-IC: for.exiting_block: +; EPILOG-NO-IC-NEXT: [[CMP:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY:%.*]] +; EPILOG-NO-IC: for.body: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NO-IC-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[SUM_02]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB:%.*]] = sub i64 [[NITER]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_1:%.*]] +; EPILOG-NO-IC: for.end.unr-lcssa.loopexit: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA_PH_PH:%.*]] = phi i32 [ [[ADD_7]], [[FOR_BODY_7]] ] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_7]], [[FOR_BODY_7]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02_UNR_PH:%.*]] = phi i32 [ [[ADD_7]], [[FOR_BODY_7]] ] +; EPILOG-NO-IC-NEXT: br label [[FOR_END_UNR_LCSSA]] +; EPILOG-NO-IC: for.end.unr-lcssa: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[SUM_0_LCSSA_PH_PH]], [[FOR_END_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_UNR_PH]], [[FOR_END_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_02_UNR_PH]], [[FOR_END_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NO-IC-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[FOR_END:%.*]] +; EPILOG-NO-IC: header.epil.preheader: +; EPILOG-NO-IC-NEXT: br label [[HEADER_EPIL:%.*]] +; EPILOG-NO-IC: header.epil: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[FOR_BODY_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[FOR_BODY_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[FOR_BODY_EPIL]] ] +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT2:%.*]], label [[FOR_EXITING_BLOCK_EPIL:%.*]] +; EPILOG-NO-IC: for.exiting_block.epil: +; EPILOG-NO-IC-NEXT: [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_EPIL]], label [[FOR_EXIT2_LOOPEXIT2]], label [[FOR_BODY_EPIL]] +; EPILOG-NO-IC: for.body.epil: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]] +; EPILOG-NO-IC-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_EPIL]] = add nsw i32 [[TMP3]], [[SUM_02_EPIL]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1 +; EPILOG-NO-IC-NEXT: [[EXITCOND_EPIL:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_EPIL]], [[N]] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_SUB]] = sub i64 [[EPIL_ITER]], 1 +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[FOR_END_EPILOG_LCSSA:%.*]], !llvm.loop !2 +; EPILOG-NO-IC: for.end.epilog-lcssa: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA_PH1:%.*]] = phi i32 [ [[ADD_EPIL]], [[FOR_BODY_EPIL]] ] +; EPILOG-NO-IC-NEXT: br label [[FOR_END]] +; EPILOG-NO-IC: for.end: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[FOR_END_UNR_LCSSA]] ], [ [[SUM_0_LCSSA_PH1]], [[FOR_END_EPILOG_LCSSA]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[SUM_0_LCSSA]] +; EPILOG-NO-IC: for.exit2.loopexit: +; EPILOG-NO-IC-NEXT: [[RETVAL_PH:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK]] ], [ [[SUM_02]], [[HEADER]] ], [ [[ADD]], [[FOR_BODY]] ], [ 42, [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1:%.*]], [[FOR_BODY_1:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_2:%.*]] ], [ [[ADD_2:%.*]], [[FOR_BODY_2:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_3:%.*]] ], [ [[ADD_3:%.*]], [[FOR_BODY_3:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_4:%.*]] ], [ [[ADD_4:%.*]], [[FOR_BODY_4:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_5:%.*]] ], [ [[ADD_5:%.*]], [[FOR_BODY_5:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_6:%.*]] ], [ [[ADD_6:%.*]], [[FOR_BODY_6:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_7:%.*]] ] +; EPILOG-NO-IC-NEXT: br label [[FOR_EXIT2:%.*]] +; EPILOG-NO-IC: for.exit2.loopexit2: +; EPILOG-NO-IC-NEXT: [[RETVAL_PH3:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK_EPIL]] ], [ [[SUM_02_EPIL]], [[HEADER_EPIL]] ] +; EPILOG-NO-IC-NEXT: br label [[FOR_EXIT2]] +; EPILOG-NO-IC: for.exit2: +; EPILOG-NO-IC-NEXT: [[RETVAL:%.*]] = phi i32 [ [[RETVAL_PH]], [[FOR_EXIT2_LOOPEXIT]] ], [ [[RETVAL_PH3]], [[FOR_EXIT2_LOOPEXIT2]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[RETVAL]] +; EPILOG-NO-IC: for.exiting_block.1: +; EPILOG-NO-IC-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_1]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_1]] +; EPILOG-NO-IC: for.body.1: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]] +; EPILOG-NO-IC-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_1]] = add nsw i32 [[TMP4]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_1:%.*]] = sub i64 [[NITER_NSUB]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_2]] +; EPILOG-NO-IC: for.exiting_block.2: +; EPILOG-NO-IC-NEXT: [[CMP_2:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_2]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_2]] +; EPILOG-NO-IC: for.body.2: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]] +; EPILOG-NO-IC-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_2]] = add nsw i32 [[TMP5]], [[ADD_1]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_1]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_2:%.*]] = sub i64 [[NITER_NSUB_1]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_3]] +; EPILOG-NO-IC: for.exiting_block.3: +; EPILOG-NO-IC-NEXT: [[CMP_3:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_3]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_3]] +; EPILOG-NO-IC: for.body.3: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]] +; EPILOG-NO-IC-NEXT: [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_3]] = add nsw i32 [[TMP6]], [[ADD_2]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_2]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_3:%.*]] = sub i64 [[NITER_NSUB_2]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_4]] +; EPILOG-NO-IC: for.exiting_block.4: +; EPILOG-NO-IC-NEXT: [[CMP_4:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_4]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_4]] +; EPILOG-NO-IC: for.body.4: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]] +; EPILOG-NO-IC-NEXT: [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_4]] = add nsw i32 [[TMP7]], [[ADD_3]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_3]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_4:%.*]] = sub i64 [[NITER_NSUB_3]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_5]] +; EPILOG-NO-IC: for.exiting_block.5: +; EPILOG-NO-IC-NEXT: [[CMP_5:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_5]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_5]] +; EPILOG-NO-IC: for.body.5: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]] +; EPILOG-NO-IC-NEXT: [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_5]] = add nsw i32 [[TMP8]], [[ADD_4]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_5:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_4]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_5:%.*]] = sub i64 [[NITER_NSUB_4]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_6]] +; EPILOG-NO-IC: for.exiting_block.6: +; EPILOG-NO-IC-NEXT: [[CMP_6:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_6]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_6]] +; EPILOG-NO-IC: for.body.6: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]] +; EPILOG-NO-IC-NEXT: [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_6]] = add nsw i32 [[TMP9]], [[ADD_5]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_6:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_5]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_6:%.*]] = sub i64 [[NITER_NSUB_5]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_7]] +; EPILOG-NO-IC: for.exiting_block.7: +; EPILOG-NO-IC-NEXT: [[CMP_7:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_7]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_7]] +; EPILOG-NO-IC: for.body.7: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]] +; EPILOG-NO-IC-NEXT: [[TMP10:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV_NEXT_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_7]] = sub i64 [[NITER_NSUB_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[NITER_NCMP_7]], label [[FOR_END_UNR_LCSSA_LOOPEXIT]], label [[HEADER]] +; +; EPILOG-LABEL: @test2( +; EPILOG-NEXT: entry: +; EPILOG-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 +; EPILOG-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 7 +; EPILOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; EPILOG-NEXT: br i1 [[TMP1]], label [[FOR_END_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] +; EPILOG: entry.new: +; EPILOG-NEXT: [[UNROLL_ITER:%.*]] = and i64 [[N]], -8 +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[FOR_BODY_7:%.*]] ] +; EPILOG-NEXT: [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[FOR_BODY_7]] ] +; EPILOG-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[FOR_BODY_7]] ] +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG: for.exiting_block: +; EPILOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY:%.*]] +; EPILOG: for.body: +; EPILOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[SUM_02]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 1 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_1:%.*]] +; EPILOG: for.end.unr-lcssa.loopexit: +; EPILOG-NEXT: br label [[FOR_END_UNR_LCSSA]] +; EPILOG: for.end.unr-lcssa: +; EPILOG-NEXT: [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[ADD_7]], [[FOR_END_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_7]], [[FOR_END_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NEXT: [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_7]], [[FOR_END_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; EPILOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[FOR_END:%.*]], label [[HEADER_EPIL_PREHEADER:%.*]] +; EPILOG: header.epil.preheader: +; EPILOG-NEXT: br label [[HEADER_EPIL:%.*]] +; EPILOG: header.epil: +; EPILOG-NEXT: [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[FOR_BODY_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NEXT: [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[FOR_BODY_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[EPIL_ITER_SUB:%.*]], [[FOR_BODY_EPIL]] ], [ [[XTRAITER]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT2:%.*]], label [[FOR_EXITING_BLOCK_EPIL:%.*]] +; EPILOG: for.exiting_block.epil: +; EPILOG-NEXT: [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_EPIL]], label [[FOR_EXIT2_LOOPEXIT2]], label [[FOR_BODY_EPIL]] +; EPILOG: for.body.epil: +; EPILOG-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]] +; EPILOG-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4 +; EPILOG-NEXT: [[ADD_EPIL]] = add nsw i32 [[TMP3]], [[SUM_02_EPIL]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1 +; EPILOG-NEXT: [[EPIL_ITER_SUB]] = add i64 [[EPIL_ITER]], -1 +; EPILOG-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[FOR_END_EPILOG_LCSSA:%.*]], label [[HEADER_EPIL]], !llvm.loop !2 +; EPILOG: for.end.epilog-lcssa: +; EPILOG-NEXT: br label [[FOR_END]] +; EPILOG: for.end: +; EPILOG-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[FOR_END_UNR_LCSSA]] ], [ [[ADD_EPIL]], [[FOR_END_EPILOG_LCSSA]] ] +; EPILOG-NEXT: ret i32 [[SUM_0_LCSSA]] +; EPILOG: for.exit2.loopexit: +; EPILOG-NEXT: [[RETVAL_PH:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK]] ], [ [[SUM_02]], [[HEADER]] ], [ [[ADD]], [[FOR_BODY]] ], [ 42, [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1:%.*]], [[FOR_BODY_1:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_2:%.*]] ], [ [[ADD_2:%.*]], [[FOR_BODY_2:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_3:%.*]] ], [ [[ADD_3:%.*]], [[FOR_BODY_3:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_4:%.*]] ], [ [[ADD_4:%.*]], [[FOR_BODY_4:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_5:%.*]] ], [ [[ADD_5:%.*]], [[FOR_BODY_5:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_6:%.*]] ], [ [[ADD_6:%.*]], [[FOR_BODY_6:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_7:%.*]] ] +; EPILOG-NEXT: br label [[FOR_EXIT2:%.*]] +; EPILOG: for.exit2.loopexit2: +; EPILOG-NEXT: [[RETVAL_PH3:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK_EPIL]] ], [ [[SUM_02_EPIL]], [[HEADER_EPIL]] ] +; EPILOG-NEXT: br label [[FOR_EXIT2]] +; EPILOG: for.exit2: +; EPILOG-NEXT: [[RETVAL:%.*]] = phi i32 [ [[RETVAL_PH]], [[FOR_EXIT2_LOOPEXIT]] ], [ [[RETVAL_PH3]], [[FOR_EXIT2_LOOPEXIT2]] ] +; EPILOG-NEXT: ret i32 [[RETVAL]] +; EPILOG: for.exiting_block.1: +; EPILOG-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_1]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_1]] +; EPILOG: for.body.1: +; EPILOG-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]] +; EPILOG-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 +; EPILOG-NEXT: [[ADD_1]] = add nsw i32 [[TMP4]], [[ADD]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = or i64 [[INDVARS_IV]], 2 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_2]] +; EPILOG: for.exiting_block.2: +; EPILOG-NEXT: [[CMP_2:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_2]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_2]] +; EPILOG: for.body.2: +; EPILOG-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]] +; EPILOG-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 +; EPILOG-NEXT: [[ADD_2]] = add nsw i32 [[TMP5]], [[ADD_1]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = or i64 [[INDVARS_IV]], 3 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_3]] +; EPILOG: for.exiting_block.3: +; EPILOG-NEXT: [[CMP_3:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_3]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_3]] +; EPILOG: for.body.3: +; EPILOG-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]] +; EPILOG-NEXT: [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 +; EPILOG-NEXT: [[ADD_3]] = add nsw i32 [[TMP6]], [[ADD_2]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = or i64 [[INDVARS_IV]], 4 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_4]] +; EPILOG: for.exiting_block.4: +; EPILOG-NEXT: [[CMP_4:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_4]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_4]] +; EPILOG: for.body.4: +; EPILOG-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]] +; EPILOG-NEXT: [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 +; EPILOG-NEXT: [[ADD_4]] = add nsw i32 [[TMP7]], [[ADD_3]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_4:%.*]] = or i64 [[INDVARS_IV]], 5 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_5]] +; EPILOG: for.exiting_block.5: +; EPILOG-NEXT: [[CMP_5:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_5]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_5]] +; EPILOG: for.body.5: +; EPILOG-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]] +; EPILOG-NEXT: [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 +; EPILOG-NEXT: [[ADD_5]] = add nsw i32 [[TMP8]], [[ADD_4]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_5:%.*]] = or i64 [[INDVARS_IV]], 6 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_6]] +; EPILOG: for.exiting_block.6: +; EPILOG-NEXT: [[CMP_6:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_6]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_6]] +; EPILOG: for.body.6: +; EPILOG-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]] +; EPILOG-NEXT: [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 +; EPILOG-NEXT: [[ADD_6]] = add nsw i32 [[TMP9]], [[ADD_5]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_6:%.*]] = or i64 [[INDVARS_IV]], 7 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_7]] +; EPILOG: for.exiting_block.7: +; EPILOG-NEXT: [[CMP_7:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_7]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_7]] +; EPILOG: for.body.7: +; EPILOG-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]] +; EPILOG-NEXT: [[TMP10:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 +; EPILOG-NEXT: [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8 +; EPILOG-NEXT: [[NITER_NSUB_7]] = add i64 [[NITER]], -8 +; EPILOG-NEXT: [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0 +; EPILOG-NEXT: br i1 [[NITER_NCMP_7]], label [[FOR_END_UNR_LCSSA_LOOPEXIT]], label [[HEADER]] +; +; PROLOG-LABEL: @test2( +; PROLOG-NEXT: entry: +; PROLOG-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 +; PROLOG-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 7 +; PROLOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; PROLOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[HEADER_PROL_LOOPEXIT:%.*]], label [[HEADER_PROL_PREHEADER:%.*]] +; PROLOG: header.prol.preheader: +; PROLOG-NEXT: br label [[HEADER_PROL:%.*]] +; PROLOG: header.prol: +; PROLOG-NEXT: [[INDVARS_IV_PROL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PROL:%.*]], [[FOR_BODY_PROL:%.*]] ], [ 0, [[HEADER_PROL_PREHEADER]] ] +; PROLOG-NEXT: [[SUM_02_PROL:%.*]] = phi i32 [ [[ADD_PROL:%.*]], [[FOR_BODY_PROL]] ], [ 0, [[HEADER_PROL_PREHEADER]] ] +; PROLOG-NEXT: [[PROL_ITER:%.*]] = phi i64 [ [[PROL_ITER_SUB:%.*]], [[FOR_BODY_PROL]] ], [ [[XTRAITER]], [[HEADER_PROL_PREHEADER]] ] +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT1:%.*]], label [[FOR_EXITING_BLOCK_PROL:%.*]] +; PROLOG: for.exiting_block.prol: +; PROLOG-NEXT: [[CMP_PROL:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_PROL]], label [[FOR_EXIT2_LOOPEXIT1]], label [[FOR_BODY_PROL]] +; PROLOG: for.body.prol: +; PROLOG-NEXT: [[ARRAYIDX_PROL:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV_PROL]] +; PROLOG-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX_PROL]], align 4 +; PROLOG-NEXT: [[ADD_PROL]] = add nsw i32 [[TMP1]], [[SUM_02_PROL]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_PROL]] = add i64 [[INDVARS_IV_PROL]], 1 +; PROLOG-NEXT: [[PROL_ITER_SUB]] = add i64 [[PROL_ITER]], -1 +; PROLOG-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_SUB]], 0 +; PROLOG-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], label [[HEADER_PROL]], !llvm.loop !2 +; PROLOG: header.prol.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[HEADER_PROL_LOOPEXIT]] +; PROLOG: header.prol.loopexit: +; PROLOG-NEXT: [[SUM_0_LCSSA_UNR:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[ADD_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP0]], 7 +; PROLOG-NEXT: br i1 [[TMP2]], label [[FOR_END:%.*]], label [[ENTRY_NEW:%.*]] +; PROLOG: entry.new: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_UNR]], [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[FOR_BODY_7:%.*]] ] +; PROLOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[SUM_02_UNR]], [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[FOR_BODY_7]] ] +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; PROLOG: for.exiting_block: +; PROLOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY:%.*]] +; PROLOG: for.body: +; PROLOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] +; PROLOG-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; PROLOG-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT:%.*]] = add i64 [[INDVARS_IV]], 1 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_1:%.*]] +; PROLOG: for.end.unr-lcssa: +; PROLOG-NEXT: br label [[FOR_END]] +; PROLOG: for.end: +; PROLOG-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_UNR]], [[HEADER_PROL_LOOPEXIT]] ], [ [[ADD_7]], [[FOR_END_UNR_LCSSA:%.*]] ] +; PROLOG-NEXT: ret i32 [[SUM_0_LCSSA]] +; PROLOG: for.exit2.loopexit: +; PROLOG-NEXT: [[RETVAL_PH:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK]] ], [ [[SUM_02]], [[HEADER]] ], [ [[ADD]], [[FOR_BODY]] ], [ 42, [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1:%.*]], [[FOR_BODY_1:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_2:%.*]] ], [ [[ADD_2:%.*]], [[FOR_BODY_2:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_3:%.*]] ], [ [[ADD_3:%.*]], [[FOR_BODY_3:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_4:%.*]] ], [ [[ADD_4:%.*]], [[FOR_BODY_4:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_5:%.*]] ], [ [[ADD_5:%.*]], [[FOR_BODY_5:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_6:%.*]] ], [ [[ADD_6:%.*]], [[FOR_BODY_6:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_7:%.*]] ] +; PROLOG-NEXT: br label [[FOR_EXIT2:%.*]] +; PROLOG: for.exit2.loopexit1: +; PROLOG-NEXT: [[RETVAL_PH2:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK_PROL]] ], [ [[SUM_02_PROL]], [[HEADER_PROL]] ] +; PROLOG-NEXT: br label [[FOR_EXIT2]] +; PROLOG: for.exit2: +; PROLOG-NEXT: [[RETVAL:%.*]] = phi i32 [ [[RETVAL_PH]], [[FOR_EXIT2_LOOPEXIT]] ], [ [[RETVAL_PH2]], [[FOR_EXIT2_LOOPEXIT1]] ] +; PROLOG-NEXT: ret i32 [[RETVAL]] +; PROLOG: for.exiting_block.1: +; PROLOG-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_1]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_1]] +; PROLOG: for.body.1: +; PROLOG-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]] +; PROLOG-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 +; PROLOG-NEXT: [[ADD_1]] = add nsw i32 [[TMP4]], [[ADD]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = add i64 [[INDVARS_IV]], 2 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_2]] +; PROLOG: for.exiting_block.2: +; PROLOG-NEXT: [[CMP_2:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_2]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_2]] +; PROLOG: for.body.2: +; PROLOG-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]] +; PROLOG-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 +; PROLOG-NEXT: [[ADD_2]] = add nsw i32 [[TMP5]], [[ADD_1]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = add i64 [[INDVARS_IV]], 3 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_3]] +; PROLOG: for.exiting_block.3: +; PROLOG-NEXT: [[CMP_3:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_3]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_3]] +; PROLOG: for.body.3: +; PROLOG-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]] +; PROLOG-NEXT: [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 +; PROLOG-NEXT: [[ADD_3]] = add nsw i32 [[TMP6]], [[ADD_2]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = add i64 [[INDVARS_IV]], 4 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_4]] +; PROLOG: for.exiting_block.4: +; PROLOG-NEXT: [[CMP_4:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_4]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_4]] +; PROLOG: for.body.4: +; PROLOG-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]] +; PROLOG-NEXT: [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 +; PROLOG-NEXT: [[ADD_4]] = add nsw i32 [[TMP7]], [[ADD_3]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_4:%.*]] = add i64 [[INDVARS_IV]], 5 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_5]] +; PROLOG: for.exiting_block.5: +; PROLOG-NEXT: [[CMP_5:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_5]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_5]] +; PROLOG: for.body.5: +; PROLOG-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]] +; PROLOG-NEXT: [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 +; PROLOG-NEXT: [[ADD_5]] = add nsw i32 [[TMP8]], [[ADD_4]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_5:%.*]] = add i64 [[INDVARS_IV]], 6 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_6]] +; PROLOG: for.exiting_block.6: +; PROLOG-NEXT: [[CMP_6:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_6]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_6]] +; PROLOG: for.body.6: +; PROLOG-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]] +; PROLOG-NEXT: [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 +; PROLOG-NEXT: [[ADD_6]] = add nsw i32 [[TMP9]], [[ADD_5]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_6:%.*]] = add i64 [[INDVARS_IV]], 7 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_7]] +; PROLOG: for.exiting_block.7: +; PROLOG-NEXT: [[CMP_7:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_7]], label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_BODY_7]] +; PROLOG: for.body.7: +; PROLOG-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]] +; PROLOG-NEXT: [[TMP10:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 +; PROLOG-NEXT: [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8 +; PROLOG-NEXT: [[EXITCOND_7:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_7]], [[N]] +; PROLOG-NEXT: br i1 [[EXITCOND_7]], label [[FOR_END_UNR_LCSSA]], label [[HEADER]] +; -; PROLOG: test2( -; PROLOG: for.exit2.loopexit: -; PROLOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %for.body ], [ 42, %for.exiting_block.1 ], [ %add.1, %for.body.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %for.body.2 ], [ 42, %for.exiting_block.3 ], -; PROLOG-NEXT: br label %for.exit2 -; PROLOG: for.exit2.loopexit1: -; PROLOG-NEXT: %retval.ph2 = phi i32 [ 42, %for.exiting_block.prol ], [ %sum.02.prol, %header.prol ] -; PROLOG-NEXT: br label %for.exit2 -; PROLOG: for.exit2: -; PROLOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph2, %for.exit2.loopexit1 ] -; PROLOG-NEXT: ret i32 %retval -; PROLOG: %indvars.iv.next.7 = add i64 %indvars.iv, 8 entry: br label %header @@ -117,8 +770,8 @@ br i1 false, label %for.exit2, label %for.exiting_block for.exiting_block: - %cmp = icmp eq i64 %n, 42 - br i1 %cmp, label %for.exit2, label %for.body + %cmp = icmp eq i64 %n, 42 + br i1 %cmp, label %for.exit2, label %for.body for.body: %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv @@ -140,42 +793,385 @@ ; test with two exiting and three exit blocks. ; the non-latch exiting block has a switch. define void @test3(i64 %trip, i64 %add) { -; EPILOG: test3( +; EPILOG-NO-IC-LABEL: @test3( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 +; EPILOG-NO-IC-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 +; EPILOG-NO-IC-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; EPILOG-NO-IC-NEXT: br i1 [[TMP1]], label [[EXIT2_LOOPEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] +; EPILOG-NO-IC: entry.new: +; EPILOG-NO-IC-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[TRIP]], [[XTRAITER]] +; EPILOG-NO-IC-NEXT: br label [[LOOP_HEADER:%.*]] +; EPILOG-NO-IC: loop_header: +; EPILOG-NO-IC-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_7:%.*]], [[LOOP_LATCH_7:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[SUM_NEXT_7:%.*]], [[LOOP_LATCH_7]] ] +; EPILOG-NO-IC-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LOOP_LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH:%.*]], label [[LOOP_EXITING_BB1:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM]], label [[LOOP_LATCH]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT:%.*]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT:%.*]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: exit3.loopexit: +; EPILOG-NO-IC-NEXT: br label [[EXIT3:%.*]] +; EPILOG-NO-IC: exit3.loopexit2: +; EPILOG-NO-IC-NEXT: br label [[EXIT3]] +; EPILOG-NO-IC: exit3: +; EPILOG-NO-IC-NEXT: ret void +; EPILOG-NO-IC: loop_latch: +; EPILOG-NO-IC-NEXT: [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT:%.*]] = add i64 [[SUM]], [[ADD:%.*]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB:%.*]] = sub i64 [[NITER]], 1 +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_1:%.*]], label [[LOOP_EXITING_BB1_1:%.*]] +; EPILOG-NO-IC: exit1.loopexit: +; EPILOG-NO-IC-NEXT: br label [[EXIT1:%.*]] +; EPILOG-NO-IC: exit1.loopexit1: +; EPILOG-NO-IC-NEXT: br label [[EXIT1]] +; EPILOG-NO-IC: exit1: +; EPILOG-NO-IC-NEXT: ret void +; EPILOG-NO-IC: exit2.loopexit.unr-lcssa.loopexit: +; EPILOG-NO-IC-NEXT: [[IV_UNR_PH:%.*]] = phi i64 [ [[IV_NEXT_7]], [[LOOP_LATCH_7]] ] +; EPILOG-NO-IC-NEXT: [[SUM_UNR_PH:%.*]] = phi i64 [ [[SUM_NEXT_7]], [[LOOP_LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br label [[EXIT2_LOOPEXIT_UNR_LCSSA]] +; EPILOG-NO-IC: exit2.loopexit.unr-lcssa: +; EPILOG-NO-IC-NEXT: [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[SUM_UNR_PH]], [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NO-IC-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[LCMP_MOD]], label [[LOOP_HEADER_EPIL_PREHEADER:%.*]], label [[EXIT2_LOOPEXIT:%.*]] +; EPILOG-NO-IC: loop_header.epil.preheader: +; EPILOG-NO-IC-NEXT: br label [[LOOP_HEADER_EPIL:%.*]] +; EPILOG-NO-IC: loop_header.epil: +; EPILOG-NO-IC-NEXT: [[IV_EPIL:%.*]] = phi i64 [ [[IV_UNR]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[IV_NEXT_EPIL:%.*]], [[LOOP_LATCH_EPIL:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_EPIL:%.*]] = phi i64 [ [[SUM_UNR]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[SUM_NEXT_EPIL:%.*]], [[LOOP_LATCH_EPIL]] ] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[LOOP_LATCH_EPIL]] ] +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_EPIL]], label [[LOOP_EXITING_BB1_EPIL:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.epil: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_EPIL]], label [[LOOP_LATCH_EPIL]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT1:%.*]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT2:%.*]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.epil: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_EPIL]] = add nuw nsw i64 [[IV_EPIL]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_EPIL]] = add i64 [[SUM_EPIL]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[CMP_EPIL:%.*]] = icmp ne i64 [[IV_NEXT_EPIL]], [[TRIP]] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_SUB]] = sub i64 [[EPIL_ITER]], 1 +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[EPIL_ITER_CMP]], label [[LOOP_HEADER_EPIL]], label [[EXIT2_LOOPEXIT_EPILOG_LCSSA:%.*]], !llvm.loop !3 +; EPILOG-NO-IC: exit2.loopexit.epilog-lcssa: +; EPILOG-NO-IC-NEXT: br label [[EXIT2_LOOPEXIT]] +; EPILOG-NO-IC: exit2.loopexit: +; EPILOG-NO-IC-NEXT: ret void +; EPILOG-NO-IC: loop_exiting_bb1.1: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_NEXT]], label [[LOOP_LATCH_1]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.1: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV_NEXT]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_1:%.*]] = add i64 [[SUM_NEXT]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_1:%.*]] = sub i64 [[NITER_NSUB]], 1 +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_2:%.*]], label [[LOOP_EXITING_BB1_2:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.2: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_NEXT_1]], label [[LOOP_LATCH_2]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.2: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV_NEXT_1]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_2:%.*]] = add i64 [[SUM_NEXT_1]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_2:%.*]] = sub i64 [[NITER_NSUB_1]], 1 +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_3:%.*]], label [[LOOP_EXITING_BB1_3:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.3: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_NEXT_2]], label [[LOOP_LATCH_3]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.3: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_3:%.*]] = add nuw nsw i64 [[IV_NEXT_2]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_3:%.*]] = add i64 [[SUM_NEXT_2]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_3:%.*]] = sub i64 [[NITER_NSUB_2]], 1 +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_4:%.*]], label [[LOOP_EXITING_BB1_4:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.4: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_NEXT_3]], label [[LOOP_LATCH_4]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.4: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_4:%.*]] = add nuw nsw i64 [[IV_NEXT_3]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_4:%.*]] = add i64 [[SUM_NEXT_3]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_4:%.*]] = sub i64 [[NITER_NSUB_3]], 1 +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_5:%.*]], label [[LOOP_EXITING_BB1_5:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.5: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_NEXT_4]], label [[LOOP_LATCH_5]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.5: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_5:%.*]] = add nuw nsw i64 [[IV_NEXT_4]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_5:%.*]] = add i64 [[SUM_NEXT_4]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_5:%.*]] = sub i64 [[NITER_NSUB_4]], 1 +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_6:%.*]], label [[LOOP_EXITING_BB1_6:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.6: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_NEXT_5]], label [[LOOP_LATCH_6]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.6: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_6:%.*]] = add nuw nsw i64 [[IV_NEXT_5]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_6:%.*]] = add i64 [[SUM_NEXT_5]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_6:%.*]] = sub i64 [[NITER_NSUB_5]], 1 +; EPILOG-NO-IC-NEXT: br i1 undef, label [[LOOP_LATCH_7]], label [[LOOP_EXITING_BB1_7:%.*]] +; EPILOG-NO-IC: loop_exiting_bb1.7: +; EPILOG-NO-IC-NEXT: switch i64 [[SUM_NEXT_6]], label [[LOOP_LATCH_7]] [ +; EPILOG-NO-IC-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NO-IC-NEXT: ] +; EPILOG-NO-IC: loop_latch.7: +; EPILOG-NO-IC-NEXT: [[IV_NEXT_7]] = add nuw nsw i64 [[IV_NEXT_6]], 1 +; EPILOG-NO-IC-NEXT: [[SUM_NEXT_7]] = add i64 [[SUM_NEXT_6]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_7]] = sub i64 [[NITER_NSUB_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NCMP_7:%.*]] = icmp ne i64 [[NITER_NSUB_7]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[NITER_NCMP_7]], label [[LOOP_HEADER]], label [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] +; +; EPILOG-LABEL: @test3( ; EPILOG-NEXT: entry: ; EPILOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 ; EPILOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 ; EPILOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 -; EPILOG-NEXT: br i1 [[TMP1]], label %exit2.loopexit.unr-lcssa, label [[ENTRY_NEW:%.*]] +; EPILOG-NEXT: br i1 [[TMP1]], label [[EXIT2_LOOPEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] ; EPILOG: entry.new: -; EPILOG-NEXT: %unroll_iter = and i64 [[TRIP]], -8 +; EPILOG-NEXT: [[UNROLL_ITER:%.*]] = and i64 [[TRIP]], -8 ; EPILOG-NEXT: br label [[LOOP_HEADER:%.*]] -; EPILOG: loop_header: -; EPILOG-NEXT: %sum = phi i64 [ 0, %entry.new ], [ %sum.next.7, %loop_latch.7 ] -; EPILOG-NEXT: %niter = phi i64 [ %unroll_iter, %entry.new ], [ %niter.nsub.7, %loop_latch.7 ] -; EPILOG: loop_exiting_bb1.7: -; EPILOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 -; EPILOG: loop_latch.7: -; EPILOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add -; EPILOG-NEXT: %niter.nsub.7 = add i64 %niter, -8 -; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.nsub.7, 0 -; EPILOG-NEXT: br i1 %niter.ncmp.7, label %exit2.loopexit.unr-lcssa.loopexit, label %loop_header - -; PROLOG: test3( +; EPILOG: loop_header: +; EPILOG-NEXT: [[SUM:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[SUM_NEXT_7:%.*]], [[LOOP_LATCH_7:%.*]] ] +; EPILOG-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LOOP_LATCH_7]] ] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH:%.*]], label [[LOOP_EXITING_BB1:%.*]] +; EPILOG: loop_exiting_bb1: +; EPILOG-NEXT: switch i64 [[SUM]], label [[LOOP_LATCH]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT:%.*]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT:%.*]] +; EPILOG-NEXT: ] +; EPILOG: exit3.loopexit: +; EPILOG-NEXT: br label [[EXIT3:%.*]] +; EPILOG: exit3.loopexit2: +; EPILOG-NEXT: br label [[EXIT3]] +; EPILOG: exit3: +; EPILOG-NEXT: ret void +; EPILOG: loop_latch: +; EPILOG-NEXT: [[SUM_NEXT:%.*]] = add i64 [[SUM]], [[ADD:%.*]] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_1:%.*]], label [[LOOP_EXITING_BB1_1:%.*]] +; EPILOG: exit1.loopexit: +; EPILOG-NEXT: br label [[EXIT1:%.*]] +; EPILOG: exit1.loopexit1: +; EPILOG-NEXT: br label [[EXIT1]] +; EPILOG: exit1: +; EPILOG-NEXT: ret void +; EPILOG: exit2.loopexit.unr-lcssa.loopexit: +; EPILOG-NEXT: br label [[EXIT2_LOOPEXIT_UNR_LCSSA]] +; EPILOG: exit2.loopexit.unr-lcssa: +; EPILOG-NEXT: [[SUM_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT_7]], [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; EPILOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[EXIT2_LOOPEXIT:%.*]], label [[LOOP_HEADER_EPIL_PREHEADER:%.*]] +; EPILOG: loop_header.epil.preheader: +; EPILOG-NEXT: br label [[LOOP_HEADER_EPIL:%.*]] +; EPILOG: loop_header.epil: +; EPILOG-NEXT: [[SUM_EPIL:%.*]] = phi i64 [ [[SUM_UNR]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[SUM_NEXT_EPIL:%.*]], [[LOOP_LATCH_EPIL:%.*]] ] +; EPILOG-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[LOOP_HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[LOOP_LATCH_EPIL]] ] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_EPIL]], label [[LOOP_EXITING_BB1_EPIL:%.*]] +; EPILOG: loop_exiting_bb1.epil: +; EPILOG-NEXT: switch i64 [[SUM_EPIL]], label [[LOOP_LATCH_EPIL]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT1:%.*]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT2:%.*]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.epil: +; EPILOG-NEXT: [[SUM_NEXT_EPIL]] = add i64 [[SUM_EPIL]], [[ADD]] +; EPILOG-NEXT: [[EPIL_ITER_SUB]] = add i64 [[EPIL_ITER]], -1 +; EPILOG-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[EXIT2_LOOPEXIT_EPILOG_LCSSA:%.*]], label [[LOOP_HEADER_EPIL]], !llvm.loop !3 +; EPILOG: exit2.loopexit.epilog-lcssa: +; EPILOG-NEXT: br label [[EXIT2_LOOPEXIT]] +; EPILOG: exit2.loopexit: +; EPILOG-NEXT: ret void +; EPILOG: loop_exiting_bb1.1: +; EPILOG-NEXT: switch i64 [[SUM_NEXT]], label [[LOOP_LATCH_1]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.1: +; EPILOG-NEXT: [[SUM_NEXT_1:%.*]] = add i64 [[SUM_NEXT]], [[ADD]] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_2:%.*]], label [[LOOP_EXITING_BB1_2:%.*]] +; EPILOG: loop_exiting_bb1.2: +; EPILOG-NEXT: switch i64 [[SUM_NEXT_1]], label [[LOOP_LATCH_2]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.2: +; EPILOG-NEXT: [[SUM_NEXT_2:%.*]] = add i64 [[SUM_NEXT_1]], [[ADD]] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_3:%.*]], label [[LOOP_EXITING_BB1_3:%.*]] +; EPILOG: loop_exiting_bb1.3: +; EPILOG-NEXT: switch i64 [[SUM_NEXT_2]], label [[LOOP_LATCH_3]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.3: +; EPILOG-NEXT: [[SUM_NEXT_3:%.*]] = add i64 [[SUM_NEXT_2]], [[ADD]] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_4:%.*]], label [[LOOP_EXITING_BB1_4:%.*]] +; EPILOG: loop_exiting_bb1.4: +; EPILOG-NEXT: switch i64 [[SUM_NEXT_3]], label [[LOOP_LATCH_4]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.4: +; EPILOG-NEXT: [[SUM_NEXT_4:%.*]] = add i64 [[SUM_NEXT_3]], [[ADD]] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_5:%.*]], label [[LOOP_EXITING_BB1_5:%.*]] +; EPILOG: loop_exiting_bb1.5: +; EPILOG-NEXT: switch i64 [[SUM_NEXT_4]], label [[LOOP_LATCH_5]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.5: +; EPILOG-NEXT: [[SUM_NEXT_5:%.*]] = add i64 [[SUM_NEXT_4]], [[ADD]] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_6:%.*]], label [[LOOP_EXITING_BB1_6:%.*]] +; EPILOG: loop_exiting_bb1.6: +; EPILOG-NEXT: switch i64 [[SUM_NEXT_5]], label [[LOOP_LATCH_6]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.6: +; EPILOG-NEXT: [[SUM_NEXT_6:%.*]] = add i64 [[SUM_NEXT_5]], [[ADD]] +; EPILOG-NEXT: br i1 undef, label [[LOOP_LATCH_7]], label [[LOOP_EXITING_BB1_7:%.*]] +; EPILOG: loop_exiting_bb1.7: +; EPILOG-NEXT: switch i64 [[SUM_NEXT_6]], label [[LOOP_LATCH_7]] [ +; EPILOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; EPILOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; EPILOG-NEXT: ] +; EPILOG: loop_latch.7: +; EPILOG-NEXT: [[SUM_NEXT_7]] = add i64 [[SUM_NEXT_6]], [[ADD]] +; EPILOG-NEXT: [[NITER_NSUB_7]] = add i64 [[NITER]], -8 +; EPILOG-NEXT: [[NITER_NCMP_7_NOT:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0 +; EPILOG-NEXT: br i1 [[NITER_NCMP_7_NOT]], label [[EXIT2_LOOPEXIT_UNR_LCSSA_LOOPEXIT]], label [[LOOP_HEADER]] +; +; PROLOG-LABEL: @test3( ; PROLOG-NEXT: entry: ; PROLOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 ; PROLOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 -; PROLOG-NEXT: [[TMP1:%.*]] = icmp eq i64 [[XTRAITER]], 0 -; PROLOG-NEXT: br i1 [[TMP1]], label %loop_header.prol.loopexit, label %loop_header.prol.preheader -; PROLOG: loop_header: -; PROLOG-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.7, %loop_latch.7 ] -; PROLOG-NEXT: %sum = phi i64 [ %sum.unr, %entry.new ], [ %sum.next.7, %loop_latch.7 ] -; PROLOG: loop_exiting_bb1.7: -; PROLOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 -; PROLOG: loop_latch.7: -; PROLOG-NEXT: %iv_next.7 = add nuw nsw i64 %iv, 8 -; PROLOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add -; PROLOG-NEXT: %cmp.7 = icmp eq i64 %iv_next.7, %trip -; PROLOG-NEXT: br i1 %cmp.7, label %exit2.loopexit.unr-lcssa, label %loop_header +; PROLOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; PROLOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[LOOP_HEADER_PROL_LOOPEXIT:%.*]], label [[LOOP_HEADER_PROL_PREHEADER:%.*]] +; PROLOG: loop_header.prol.preheader: +; PROLOG-NEXT: br label [[LOOP_HEADER_PROL:%.*]] +; PROLOG: loop_header.prol: +; PROLOG-NEXT: [[IV_PROL:%.*]] = phi i64 [ 0, [[LOOP_HEADER_PROL_PREHEADER]] ], [ [[IV_NEXT_PROL:%.*]], [[LOOP_LATCH_PROL:%.*]] ] +; PROLOG-NEXT: [[SUM_PROL:%.*]] = phi i64 [ 0, [[LOOP_HEADER_PROL_PREHEADER]] ], [ [[SUM_NEXT_PROL:%.*]], [[LOOP_LATCH_PROL]] ] +; PROLOG-NEXT: [[PROL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[LOOP_HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_SUB:%.*]], [[LOOP_LATCH_PROL]] ] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_PROL]], label [[LOOP_EXITING_BB1_PROL:%.*]] +; PROLOG: loop_exiting_bb1.prol: +; PROLOG-NEXT: switch i64 [[SUM_PROL]], label [[LOOP_LATCH_PROL]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT1:%.*]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT2:%.*]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.prol: +; PROLOG-NEXT: [[IV_NEXT_PROL]] = add nuw nsw i64 [[IV_PROL]], 1 +; PROLOG-NEXT: [[SUM_NEXT_PROL]] = add i64 [[SUM_PROL]], [[ADD:%.*]] +; PROLOG-NEXT: [[PROL_ITER_SUB]] = add i64 [[PROL_ITER]], -1 +; PROLOG-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_SUB]], 0 +; PROLOG-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label [[LOOP_HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], label [[LOOP_HEADER_PROL]], !llvm.loop !3 +; PROLOG: loop_header.prol.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[LOOP_HEADER_PROL_LOOPEXIT]] +; PROLOG: loop_header.prol.loopexit: +; PROLOG-NEXT: [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_PROL]], [[LOOP_HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[SUM_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[SUM_NEXT_PROL]], [[LOOP_HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; PROLOG-NEXT: br i1 [[TMP1]], label [[EXIT2_LOOPEXIT:%.*]], label [[ENTRY_NEW:%.*]] +; PROLOG: entry.new: +; PROLOG-NEXT: br label [[LOOP_HEADER:%.*]] +; PROLOG: loop_header: +; PROLOG-NEXT: [[IV:%.*]] = phi i64 [ [[IV_UNR]], [[ENTRY_NEW]] ], [ [[IV_NEXT_7:%.*]], [[LOOP_LATCH_7:%.*]] ] +; PROLOG-NEXT: [[SUM:%.*]] = phi i64 [ [[SUM_UNR]], [[ENTRY_NEW]] ], [ [[SUM_NEXT_7:%.*]], [[LOOP_LATCH_7]] ] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH:%.*]], label [[LOOP_EXITING_BB1:%.*]] +; PROLOG: loop_exiting_bb1: +; PROLOG-NEXT: switch i64 [[SUM]], label [[LOOP_LATCH]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT:%.*]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT:%.*]] +; PROLOG-NEXT: ] +; PROLOG: exit3.loopexit: +; PROLOG-NEXT: br label [[EXIT3:%.*]] +; PROLOG: exit3.loopexit2: +; PROLOG-NEXT: br label [[EXIT3]] +; PROLOG: exit3: +; PROLOG-NEXT: ret void +; PROLOG: loop_latch: +; PROLOG-NEXT: [[SUM_NEXT:%.*]] = add i64 [[SUM]], [[ADD]] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_1:%.*]], label [[LOOP_EXITING_BB1_1:%.*]] +; PROLOG: exit1.loopexit: +; PROLOG-NEXT: br label [[EXIT1:%.*]] +; PROLOG: exit1.loopexit1: +; PROLOG-NEXT: br label [[EXIT1]] +; PROLOG: exit1: +; PROLOG-NEXT: ret void +; PROLOG: exit2.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[EXIT2_LOOPEXIT]] +; PROLOG: exit2.loopexit: +; PROLOG-NEXT: ret void +; PROLOG: loop_exiting_bb1.1: +; PROLOG-NEXT: switch i64 [[SUM_NEXT]], label [[LOOP_LATCH_1]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.1: +; PROLOG-NEXT: [[SUM_NEXT_1:%.*]] = add i64 [[SUM_NEXT]], [[ADD]] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_2:%.*]], label [[LOOP_EXITING_BB1_2:%.*]] +; PROLOG: loop_exiting_bb1.2: +; PROLOG-NEXT: switch i64 [[SUM_NEXT_1]], label [[LOOP_LATCH_2]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.2: +; PROLOG-NEXT: [[SUM_NEXT_2:%.*]] = add i64 [[SUM_NEXT_1]], [[ADD]] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_3:%.*]], label [[LOOP_EXITING_BB1_3:%.*]] +; PROLOG: loop_exiting_bb1.3: +; PROLOG-NEXT: switch i64 [[SUM_NEXT_2]], label [[LOOP_LATCH_3]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.3: +; PROLOG-NEXT: [[SUM_NEXT_3:%.*]] = add i64 [[SUM_NEXT_2]], [[ADD]] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_4:%.*]], label [[LOOP_EXITING_BB1_4:%.*]] +; PROLOG: loop_exiting_bb1.4: +; PROLOG-NEXT: switch i64 [[SUM_NEXT_3]], label [[LOOP_LATCH_4]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.4: +; PROLOG-NEXT: [[SUM_NEXT_4:%.*]] = add i64 [[SUM_NEXT_3]], [[ADD]] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_5:%.*]], label [[LOOP_EXITING_BB1_5:%.*]] +; PROLOG: loop_exiting_bb1.5: +; PROLOG-NEXT: switch i64 [[SUM_NEXT_4]], label [[LOOP_LATCH_5]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.5: +; PROLOG-NEXT: [[SUM_NEXT_5:%.*]] = add i64 [[SUM_NEXT_4]], [[ADD]] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_6:%.*]], label [[LOOP_EXITING_BB1_6:%.*]] +; PROLOG: loop_exiting_bb1.6: +; PROLOG-NEXT: switch i64 [[SUM_NEXT_5]], label [[LOOP_LATCH_6]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.6: +; PROLOG-NEXT: [[SUM_NEXT_6:%.*]] = add i64 [[SUM_NEXT_5]], [[ADD]] +; PROLOG-NEXT: br i1 undef, label [[LOOP_LATCH_7]], label [[LOOP_EXITING_BB1_7:%.*]] +; PROLOG: loop_exiting_bb1.7: +; PROLOG-NEXT: switch i64 [[SUM_NEXT_6]], label [[LOOP_LATCH_7]] [ +; PROLOG-NEXT: i64 24, label [[EXIT1_LOOPEXIT]] +; PROLOG-NEXT: i64 42, label [[EXIT3_LOOPEXIT]] +; PROLOG-NEXT: ] +; PROLOG: loop_latch.7: +; PROLOG-NEXT: [[IV_NEXT_7]] = add nuw nsw i64 [[IV]], 8 +; PROLOG-NEXT: [[SUM_NEXT_7]] = add i64 [[SUM_NEXT_6]], [[ADD]] +; PROLOG-NEXT: [[CMP_7_NOT:%.*]] = icmp eq i64 [[IV_NEXT_7]], [[TRIP]] +; PROLOG-NEXT: br i1 [[CMP_7_NOT]], label [[EXIT2_LOOPEXIT_UNR_LCSSA:%.*]], label [[LOOP_HEADER]] +; + entry: br label %loop_header @@ -185,10 +1181,10 @@ br i1 undef, label %loop_latch, label %loop_exiting_bb1 loop_exiting_bb1: - switch i64 %sum, label %loop_latch [ - i64 24, label %exit1 - i64 42, label %exit3 - ] + switch i64 %sum, label %loop_latch [ + i64 24, label %exit1 + i64 42, label %exit3 + ] exit3: ret void @@ -200,7 +1196,7 @@ br i1 %cmp, label %loop_header, label %exit2.loopexit exit1: - ret void + ret void exit2.loopexit: ret void @@ -209,13 +1205,76 @@ ; FIXME: Support multiple exiting blocks to the same latch exit block. ; Three exiting blocks where header and latch exit to same LatchExit. define i32 @hdr_latch_same_exit(i32* nocapture %a, i64 %n, i1 %cond) { -; EPILOG: hdr_latch_same_exit( -; EPILOG-NOT: .unr -; EPILOG-NOT: .epil +; EPILOG-NO-IC-LABEL: @hdr_latch_same_exit( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NO-IC-NEXT: br i1 [[COND:%.*]], label [[LATCHEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG-NO-IC: for.exiting_block: +; EPILOG-NO-IC-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP]], label [[FOR_EXIT2:%.*]], label [[LATCH]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NO-IC-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NO-IC-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG-NO-IC: latchExit: +; EPILOG-NO-IC-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[HEADER]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[RESULT]] +; EPILOG-NO-IC: for.exit2: +; EPILOG-NO-IC-NEXT: ret i32 42 +; +; EPILOG-LABEL: @hdr_latch_same_exit( +; EPILOG-NEXT: entry: +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NEXT: br i1 [[COND:%.*]], label [[LATCHEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG: for.exiting_block: +; EPILOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NEXT: br i1 [[CMP]], label [[FOR_EXIT2:%.*]], label [[LATCH]] +; EPILOG: latch: +; EPILOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG: latchExit: +; EPILOG-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[HEADER]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NEXT: ret i32 [[RESULT]] +; EPILOG: for.exit2: +; EPILOG-NEXT: ret i32 42 +; +; PROLOG-LABEL: @hdr_latch_same_exit( +; PROLOG-NEXT: entry: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; PROLOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; PROLOG-NEXT: br i1 [[COND:%.*]], label [[LATCHEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; PROLOG: for.exiting_block: +; PROLOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; PROLOG-NEXT: br i1 [[CMP]], label [[FOR_EXIT2:%.*]], label [[LATCH]] +; PROLOG: latch: +; PROLOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; PROLOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; PROLOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; PROLOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; PROLOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; PROLOG: latchExit: +; PROLOG-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[HEADER]] ], [ [[ADD]], [[LATCH]] ] +; PROLOG-NEXT: ret i32 [[RESULT]] +; PROLOG: for.exit2: +; PROLOG-NEXT: ret i32 42 +; -; PROLOG: hdr_latch_same_exit( -; PROLOG-NOT: .unr -; PROLOG-NOT: .prol entry: br label %header @@ -225,8 +1284,8 @@ br i1 %cond, label %latchExit, label %for.exiting_block for.exiting_block: - %cmp = icmp eq i64 %n, 42 - br i1 %cmp, label %for.exit2, label %latch + %cmp = icmp eq i64 %n, 42 + br i1 %cmp, label %for.exit2, label %latch latch: ; preds = %latch, %entry %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv @@ -248,13 +1307,76 @@ ; non-header ; FIXME: We should unroll this loop. define i32 @otherblock_latch_same_exit(i32* nocapture %a, i64 %n, i1 %cond) { -; EPILOG: otherblock_latch_same_exit( -; EPILOG-NOT: .unr -; EPILOG-NOT: .epil +; EPILOG-NO-IC-LABEL: @otherblock_latch_same_exit( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NO-IC-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG-NO-IC: for.exiting_block: +; EPILOG-NO-IC-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NO-IC-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NO-IC-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG-NO-IC: latchExit: +; EPILOG-NO-IC-NEXT: [[RESULT:%.*]] = phi i32 [ 2, [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[RESULT]] +; EPILOG-NO-IC: for.exit2: +; EPILOG-NO-IC-NEXT: ret i32 42 +; +; EPILOG-LABEL: @otherblock_latch_same_exit( +; EPILOG-NEXT: entry: +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG: for.exiting_block: +; EPILOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; EPILOG: latch: +; EPILOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG: latchExit: +; EPILOG-NEXT: [[RESULT:%.*]] = phi i32 [ 2, [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NEXT: ret i32 [[RESULT]] +; EPILOG: for.exit2: +; EPILOG-NEXT: ret i32 42 +; +; PROLOG-LABEL: @otherblock_latch_same_exit( +; PROLOG-NEXT: entry: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; PROLOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; PROLOG-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; PROLOG: for.exiting_block: +; PROLOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; PROLOG-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; PROLOG: latch: +; PROLOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; PROLOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; PROLOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; PROLOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; PROLOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; PROLOG: latchExit: +; PROLOG-NEXT: [[RESULT:%.*]] = phi i32 [ 2, [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; PROLOG-NEXT: ret i32 [[RESULT]] +; PROLOG: for.exit2: +; PROLOG-NEXT: ret i32 42 +; -; PROLOG: otherblock_latch_same_exit( -; PROLOG-NOT: .unr -; PROLOG-NOT: .prol entry: br label %header @@ -264,8 +1386,8 @@ br i1 %cond, label %for.exit2, label %for.exiting_block for.exiting_block: - %cmp = icmp eq i64 %n, 42 - br i1 %cmp, label %latchExit, label %latch + %cmp = icmp eq i64 %n, 42 + br i1 %cmp, label %latchExit, label %latch latch: ; preds = %latch, %entry %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv @@ -288,13 +1410,76 @@ ; Same as above test except the incoming value for latch Phi is from the header ; FIXME: We should be able to runtime unroll. define i32 @otherblock_latch_same_exit2(i32* nocapture %a, i64 %n, i1 %cond) { -; EPILOG: otherblock_latch_same_exit2( -; EPILOG-NOT: .unr -; EPILOG-NOT: .epil +; EPILOG-NO-IC-LABEL: @otherblock_latch_same_exit2( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NO-IC-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG-NO-IC: for.exiting_block: +; EPILOG-NO-IC-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NO-IC-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NO-IC-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG-NO-IC: latchExit: +; EPILOG-NO-IC-NEXT: [[RESULT:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[RESULT]] +; EPILOG-NO-IC: for.exit2: +; EPILOG-NO-IC-NEXT: ret i32 42 +; +; EPILOG-LABEL: @otherblock_latch_same_exit2( +; EPILOG-NEXT: entry: +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG: for.exiting_block: +; EPILOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; EPILOG: latch: +; EPILOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG: latchExit: +; EPILOG-NEXT: [[RESULT:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NEXT: ret i32 [[RESULT]] +; EPILOG: for.exit2: +; EPILOG-NEXT: ret i32 42 +; +; PROLOG-LABEL: @otherblock_latch_same_exit2( +; PROLOG-NEXT: entry: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; PROLOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; PROLOG-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; PROLOG: for.exiting_block: +; PROLOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; PROLOG-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; PROLOG: latch: +; PROLOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; PROLOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; PROLOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; PROLOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; PROLOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; PROLOG: latchExit: +; PROLOG-NEXT: [[RESULT:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; PROLOG-NEXT: ret i32 [[RESULT]] +; PROLOG: for.exit2: +; PROLOG-NEXT: ret i32 42 +; -; PROLOG: otherblock_latch_same_exit2( -; PROLOG-NOT: .unr -; PROLOG-NOT: .prol entry: br label %header @@ -304,8 +1489,8 @@ br i1 %cond, label %for.exit2, label %for.exiting_block for.exiting_block: - %cmp = icmp eq i64 %n, 42 - br i1 %cmp, label %latchExit, label %latch + %cmp = icmp eq i64 %n, 42 + br i1 %cmp, label %latchExit, label %latch latch: ; preds = %latch, %entry %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv @@ -329,13 +1514,76 @@ ; for.exiting_block. ; FIXME: We should be able to runtime unroll. define i32 @otherblock_latch_same_exit3(i32* nocapture %a, i64 %n, i1 %cond) { -; EPILOG: otherblock_latch_same_exit3( -; EPILOG-NOT: .unr -; EPILOG-NOT: .epil +; EPILOG-NO-IC-LABEL: @otherblock_latch_same_exit3( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NO-IC-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG-NO-IC: for.exiting_block: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NO-IC-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NO-IC-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NO-IC-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG-NO-IC: latchExit: +; EPILOG-NO-IC-NEXT: [[RESULT:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[RESULT]] +; EPILOG-NO-IC: for.exit2: +; EPILOG-NO-IC-NEXT: ret i32 42 +; +; EPILOG-LABEL: @otherblock_latch_same_exit3( +; EPILOG-NEXT: entry: +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; EPILOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; EPILOG-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG: for.exiting_block: +; EPILOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; EPILOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; EPILOG-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; EPILOG: latch: +; EPILOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; EPILOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; EPILOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; EPILOG: latchExit: +; EPILOG-NEXT: [[RESULT:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; EPILOG-NEXT: ret i32 [[RESULT]] +; EPILOG: for.exit2: +; EPILOG-NEXT: ret i32 42 +; +; PROLOG-LABEL: @otherblock_latch_same_exit3( +; PROLOG-NEXT: entry: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; PROLOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ] +; PROLOG-NEXT: br i1 [[COND:%.*]], label [[FOR_EXIT2:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; PROLOG: for.exiting_block: +; PROLOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; PROLOG-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; PROLOG-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]] +; PROLOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42 +; PROLOG-NEXT: br i1 [[CMP]], label [[LATCHEXIT:%.*]], label [[LATCH]] +; PROLOG: latch: +; PROLOG-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; PROLOG-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]] +; PROLOG-NEXT: br i1 [[EXITCOND]], label [[LATCHEXIT]], label [[HEADER]] +; PROLOG: latchExit: +; PROLOG-NEXT: [[RESULT:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[LATCH]] ] +; PROLOG-NEXT: ret i32 [[RESULT]] +; PROLOG: for.exit2: +; PROLOG-NEXT: ret i32 42 +; -; PROLOG: otherblock_latch_same_exit3( -; PROLOG-NOT: .unr -; PROLOG-NOT: .prol entry: br label %header @@ -345,11 +1593,11 @@ br i1 %cond, label %for.exit2, label %for.exiting_block for.exiting_block: - %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv - %0 = load i32, i32* %arrayidx, align 4 - %add = add nsw i32 %0, %sum.02 - %cmp = icmp eq i64 %n, 42 - br i1 %cmp, label %latchExit, label %latch + %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv + %0 = load i32, i32* %arrayidx, align 4 + %add = add nsw i32 %0, %sum.02 + %cmp = icmp eq i64 %n, 42 + br i1 %cmp, label %latchExit, label %latch latch: ; preds = %latch, %entry %indvars.iv.next = add i64 %indvars.iv, 1 @@ -367,13 +1615,55 @@ ; FIXME: Support multiple exiting blocks to the unique exit block (LatchExit). ; Only 2 blocks in loop: header and latch where both exit to same LatchExit. define void @unique_exit(i32 %arg) { -; EPILOG: unique_exit( -; EPILOG-NOT: .unr -; EPILOG-NOT: .epil +; EPILOG-NO-IC-LABEL: @unique_exit( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: [[I:%.*]] = icmp sgt i32 undef, [[ARG:%.*]] +; EPILOG-NO-IC-NEXT: br i1 [[I]], label [[PREHEADER:%.*]], label [[RETURNBLOCK:%.*]] +; EPILOG-NO-IC: preheader: +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[I4:%.*]] = phi i32 [ [[INC:%.*]], [[LATCH:%.*]] ], [ [[ARG]], [[PREHEADER]] ] +; EPILOG-NO-IC-NEXT: [[INC]] = add nsw i32 [[I4]], 1 +; EPILOG-NO-IC-NEXT: br i1 true, label [[LATCHEXIT:%.*]], label [[LATCH]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], undef +; EPILOG-NO-IC-NEXT: br i1 [[CMP]], label [[HEADER]], label [[LATCHEXIT]] +; EPILOG-NO-IC: latchExit: +; EPILOG-NO-IC-NEXT: [[I2_PH:%.*]] = phi i32 [ [[I4]], [[HEADER]] ], [ -1, [[LATCH]] ] +; EPILOG-NO-IC-NEXT: br label [[RETURNBLOCK]] +; EPILOG-NO-IC: returnblock: +; EPILOG-NO-IC-NEXT: [[I2:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[I2_PH]], [[LATCHEXIT]] ] +; EPILOG-NO-IC-NEXT: ret void +; +; EPILOG-LABEL: @unique_exit( +; EPILOG-NEXT: entry: +; EPILOG-NEXT: br i1 false, label [[PREHEADER:%.*]], label [[RETURNBLOCK:%.*]] +; EPILOG: preheader: +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: br i1 true, label [[LATCHEXIT:%.*]], label [[LATCH:%.*]] +; EPILOG: latch: +; EPILOG-NEXT: br i1 undef, label [[HEADER]], label [[LATCHEXIT]] +; EPILOG: latchExit: +; EPILOG-NEXT: br label [[RETURNBLOCK]] +; EPILOG: returnblock: +; EPILOG-NEXT: ret void +; +; PROLOG-LABEL: @unique_exit( +; PROLOG-NEXT: entry: +; PROLOG-NEXT: br i1 false, label [[PREHEADER:%.*]], label [[RETURNBLOCK:%.*]] +; PROLOG: preheader: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: br i1 true, label [[LATCHEXIT:%.*]], label [[LATCH:%.*]] +; PROLOG: latch: +; PROLOG-NEXT: br i1 undef, label [[HEADER]], label [[LATCHEXIT]] +; PROLOG: latchExit: +; PROLOG-NEXT: br label [[RETURNBLOCK]] +; PROLOG: returnblock: +; PROLOG-NEXT: ret void +; -; PROLOG: unique_exit( -; PROLOG-NOT: .unr -; PROLOG-NOT: .prol entry: %i = icmp sgt i32 undef, %arg br i1 %i, label %preheader, label %returnblock @@ -402,31 +1692,6 @@ ; two exiting and two exit blocks. ; the non-latch exiting block has duplicate edges to the non-latch exit block. define i64 @test5(i64 %trip, i64 %add, i1 %cond) { -; EPILOG: test5( -; EPILOG: exit1.loopexit: -; EPILOG-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.2, %loop_exiting.2 ], -; EPILOG-NEXT: br label %exit1 -; EPILOG: exit1.loopexit2: -; EPILOG-NEXT: %ivy.epil = add i64 %iv.epil, %add -; EPILOG-NEXT: br label %exit1 -; EPILOG: exit1: -; EPILOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.epil, %exit1.loopexit2 ] -; EPILOG-NEXT: ret i64 %result -; EPILOG: loop_latch.7: -; EPILOG: %niter.nsub.7 = add i64 %niter, -8 - -; PROLOG: test5( -; PROLOG: exit1.loopexit: -; PROLOG-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.2, %loop_exiting.2 ], -; PROLOG-NEXT: br label %exit1 -; PROLOG: exit1.loopexit1: -; PROLOG-NEXT: %ivy.prol = add i64 %iv.prol, %add -; PROLOG-NEXT: br label %exit1 -; PROLOG: exit1: -; PROLOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.prol, %exit1.loopexit1 ] -; PROLOG-NEXT: ret i64 %result -; PROLOG: loop_latch.7: -; PROLOG: %iv_next.7 = add nuw nsw i64 %iv, 8 entry: br label %loop_header @@ -436,11 +1701,11 @@ br i1 %cond, label %loop_latch, label %loop_exiting loop_exiting: - %ivy = add i64 %iv, %add - switch i64 %sum, label %loop_latch [ - i64 24, label %exit1 - i64 42, label %exit1 - ] + %ivy = add i64 %iv, %add + switch i64 %sum, label %loop_latch [ + i64 24, label %exit1 + i64 42, label %exit1 + ] loop_latch: %iv_next = add nuw nsw i64 %iv, 1 @@ -449,8 +1714,8 @@ br i1 %cmp, label %loop_header, label %latchexit exit1: - %result = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ] - ret i64 %result + %result = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ] + ret i64 %result latchexit: ret i64 %sum.next @@ -458,31 +1723,418 @@ ; test when exit blocks have successors. define i32 @test6(i32* nocapture %a, i64 %n, i1 %cond, i32 %x) { -; EPILOG: test6( -; EPILOG: for.exit2.loopexit: -; EPILOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %latch ], [ 42, %for.exiting_block.1 ], [ %add.1, %latch.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %latch.2 ], -; EPILOG-NEXT: br label %for.exit2 -; EPILOG: for.exit2.loopexit2: -; EPILOG-NEXT: %retval.ph3 = phi i32 [ 42, %for.exiting_block.epil ], [ %sum.02.epil, %header.epil ] -; EPILOG-NEXT: br label %for.exit2 -; EPILOG: for.exit2: -; EPILOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph3, %for.exit2.loopexit2 ] -; EPILOG-NEXT: br i1 %cond, label %exit_true, label %exit_false -; EPILOG: latch.7: -; EPILOG: %niter.nsub.7 = add i64 %niter, -8 +; EPILOG-NO-IC-LABEL: @test6( +; EPILOG-NO-IC-NEXT: entry: +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 +; EPILOG-NO-IC-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 7 +; EPILOG-NO-IC-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; EPILOG-NO-IC-NEXT: br i1 [[TMP1]], label [[LATCH_EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] +; EPILOG-NO-IC: entry.new: +; EPILOG-NO-IC-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]] +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ] +; EPILOG-NO-IC-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG-NO-IC: for.exiting_block: +; EPILOG-NO-IC-NEXT: [[CMP:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH:%.*]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NO-IC-NEXT: [[LOAD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD]], [[SUM_02]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB:%.*]] = sub i64 [[NITER]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_1:%.*]] +; EPILOG-NO-IC: latch_exit.unr-lcssa.loopexit: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA_PH_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_7]], [[LATCH_7]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02_UNR_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br label [[LATCH_EXIT_UNR_LCSSA]] +; EPILOG-NO-IC: latch_exit.unr-lcssa: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[SUM_0_LCSSA_PH_PH]], [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_UNR_PH]], [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_02_UNR_PH]], [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NO-IC-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCH_EXIT:%.*]] +; EPILOG-NO-IC: header.epil.preheader: +; EPILOG-NO-IC-NEXT: br label [[HEADER_EPIL:%.*]] +; EPILOG-NO-IC: header.epil: +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NO-IC-NEXT: [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[LATCH_EPIL]] ] +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT2:%.*]], label [[FOR_EXITING_BLOCK_EPIL:%.*]] +; EPILOG-NO-IC: for.exiting_block.epil: +; EPILOG-NO-IC-NEXT: [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_EPIL]], label [[FOR_EXIT2_LOOPEXIT2]], label [[LATCH_EPIL]] +; EPILOG-NO-IC: latch.epil: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]] +; EPILOG-NO-IC-NEXT: [[LOAD_EPIL:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_EPIL]] = add nsw i32 [[LOAD_EPIL]], [[SUM_02_EPIL]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1 +; EPILOG-NO-IC-NEXT: [[EXITCOND_EPIL:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_EPIL]], [[N]] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_SUB]] = sub i64 [[EPIL_ITER]], 1 +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[LATCH_EXIT_EPILOG_LCSSA:%.*]], !llvm.loop !5 +; EPILOG-NO-IC: latch_exit.epilog-lcssa: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA_PH1:%.*]] = phi i32 [ [[ADD_EPIL]], [[LATCH_EPIL]] ] +; EPILOG-NO-IC-NEXT: br label [[LATCH_EXIT]] +; EPILOG-NO-IC: latch_exit: +; EPILOG-NO-IC-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCH_EXIT_UNR_LCSSA]] ], [ [[SUM_0_LCSSA_PH1]], [[LATCH_EXIT_EPILOG_LCSSA]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[SUM_0_LCSSA]] +; EPILOG-NO-IC: for.exit2.loopexit: +; EPILOG-NO-IC-NEXT: [[RETVAL_PH:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK]] ], [ [[SUM_02]], [[HEADER]] ], [ [[ADD]], [[LATCH]] ], [ 42, [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1:%.*]], [[LATCH_1:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_2:%.*]] ], [ [[ADD_2:%.*]], [[LATCH_2:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_3:%.*]] ], [ [[ADD_3:%.*]], [[LATCH_3:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_4:%.*]] ], [ [[ADD_4:%.*]], [[LATCH_4:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_5:%.*]] ], [ [[ADD_5:%.*]], [[LATCH_5:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_6:%.*]] ], [ [[ADD_6:%.*]], [[LATCH_6:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_7:%.*]] ] +; EPILOG-NO-IC-NEXT: br label [[FOR_EXIT2:%.*]] +; EPILOG-NO-IC: for.exit2.loopexit2: +; EPILOG-NO-IC-NEXT: [[RETVAL_PH3:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK_EPIL]] ], [ [[SUM_02_EPIL]], [[HEADER_EPIL]] ] +; EPILOG-NO-IC-NEXT: br label [[FOR_EXIT2]] +; EPILOG-NO-IC: for.exit2: +; EPILOG-NO-IC-NEXT: [[RETVAL:%.*]] = phi i32 [ [[RETVAL_PH]], [[FOR_EXIT2_LOOPEXIT]] ], [ [[RETVAL_PH3]], [[FOR_EXIT2_LOOPEXIT2]] ] +; EPILOG-NO-IC-NEXT: [[ADDX:%.*]] = add i32 [[RETVAL]], [[X:%.*]] +; EPILOG-NO-IC-NEXT: br i1 [[COND:%.*]], label [[EXIT_TRUE:%.*]], label [[EXIT_FALSE:%.*]] +; EPILOG-NO-IC: exit_true: +; EPILOG-NO-IC-NEXT: ret i32 [[RETVAL]] +; EPILOG-NO-IC: exit_false: +; EPILOG-NO-IC-NEXT: ret i32 [[ADDX]] +; EPILOG-NO-IC: for.exiting_block.1: +; EPILOG-NO-IC-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_1]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_1]] +; EPILOG-NO-IC: latch.1: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]] +; EPILOG-NO-IC-NEXT: [[LOAD_1:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_1]] = add nsw i32 [[LOAD_1]], [[ADD]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_1:%.*]] = sub i64 [[NITER_NSUB]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_2]] +; EPILOG-NO-IC: for.exiting_block.2: +; EPILOG-NO-IC-NEXT: [[CMP_2:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_2]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_2]] +; EPILOG-NO-IC: latch.2: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]] +; EPILOG-NO-IC-NEXT: [[LOAD_2:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_2]] = add nsw i32 [[LOAD_2]], [[ADD_1]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_1]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_2:%.*]] = sub i64 [[NITER_NSUB_1]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_3]] +; EPILOG-NO-IC: for.exiting_block.3: +; EPILOG-NO-IC-NEXT: [[CMP_3:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_3]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_3]] +; EPILOG-NO-IC: latch.3: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]] +; EPILOG-NO-IC-NEXT: [[LOAD_3:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_3]] = add nsw i32 [[LOAD_3]], [[ADD_2]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_2]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_3:%.*]] = sub i64 [[NITER_NSUB_2]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_4]] +; EPILOG-NO-IC: for.exiting_block.4: +; EPILOG-NO-IC-NEXT: [[CMP_4:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_4]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_4]] +; EPILOG-NO-IC: latch.4: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]] +; EPILOG-NO-IC-NEXT: [[LOAD_4:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_4]] = add nsw i32 [[LOAD_4]], [[ADD_3]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_3]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_4:%.*]] = sub i64 [[NITER_NSUB_3]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_5]] +; EPILOG-NO-IC: for.exiting_block.5: +; EPILOG-NO-IC-NEXT: [[CMP_5:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_5]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_5]] +; EPILOG-NO-IC: latch.5: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]] +; EPILOG-NO-IC-NEXT: [[LOAD_5:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_5]] = add nsw i32 [[LOAD_5]], [[ADD_4]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_5:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_4]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_5:%.*]] = sub i64 [[NITER_NSUB_4]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_6]] +; EPILOG-NO-IC: for.exiting_block.6: +; EPILOG-NO-IC-NEXT: [[CMP_6:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_6]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_6]] +; EPILOG-NO-IC: latch.6: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]] +; EPILOG-NO-IC-NEXT: [[LOAD_6:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_6]] = add nsw i32 [[LOAD_6]], [[ADD_5]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_6:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_5]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_6:%.*]] = sub i64 [[NITER_NSUB_5]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_7]] +; EPILOG-NO-IC: for.exiting_block.7: +; EPILOG-NO-IC-NEXT: [[CMP_7:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NO-IC-NEXT: br i1 [[CMP_7]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_7]] +; EPILOG-NO-IC: latch.7: +; EPILOG-NO-IC-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]] +; EPILOG-NO-IC-NEXT: [[LOAD_7:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 +; EPILOG-NO-IC-NEXT: [[ADD_7]] = add nsw i32 [[LOAD_7]], [[ADD_6]] +; EPILOG-NO-IC-NEXT: [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV_NEXT_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_7]] = sub i64 [[NITER_NSUB_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[NITER_NCMP_7]], label [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT]], label [[HEADER]] +; +; EPILOG-LABEL: @test6( +; EPILOG-NEXT: entry: +; EPILOG-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 +; EPILOG-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 7 +; EPILOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; EPILOG-NEXT: br i1 [[TMP1]], label [[LATCH_EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]] +; EPILOG: entry.new: +; EPILOG-NEXT: [[UNROLL_ITER:%.*]] = and i64 [[N]], -8 +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ] +; EPILOG-NEXT: [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ] +; EPILOG-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[ENTRY_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LATCH_7]] ] +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; EPILOG: for.exiting_block: +; EPILOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH:%.*]] +; EPILOG: latch: +; EPILOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; EPILOG-NEXT: [[LOAD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; EPILOG-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD]], [[SUM_02]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 1 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_1:%.*]] +; EPILOG: latch_exit.unr-lcssa.loopexit: +; EPILOG-NEXT: br label [[LATCH_EXIT_UNR_LCSSA]] +; EPILOG: latch_exit.unr-lcssa: +; EPILOG-NEXT: [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[ADD_7]], [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_7]], [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NEXT: [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_7]], [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT]] ] +; EPILOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; EPILOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[LATCH_EXIT:%.*]], label [[HEADER_EPIL_PREHEADER:%.*]] +; EPILOG: header.epil.preheader: +; EPILOG-NEXT: br label [[HEADER_EPIL:%.*]] +; EPILOG: header.epil: +; EPILOG-NEXT: [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NEXT: [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[EPIL_ITER_SUB:%.*]], [[LATCH_EPIL]] ], [ [[XTRAITER]], [[HEADER_EPIL_PREHEADER]] ] +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT2:%.*]], label [[FOR_EXITING_BLOCK_EPIL:%.*]] +; EPILOG: for.exiting_block.epil: +; EPILOG-NEXT: [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_EPIL]], label [[FOR_EXIT2_LOOPEXIT2]], label [[LATCH_EPIL]] +; EPILOG: latch.epil: +; EPILOG-NEXT: [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]] +; EPILOG-NEXT: [[LOAD_EPIL:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4 +; EPILOG-NEXT: [[ADD_EPIL]] = add nsw i32 [[LOAD_EPIL]], [[SUM_02_EPIL]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1 +; EPILOG-NEXT: [[EPIL_ITER_SUB]] = add i64 [[EPIL_ITER]], -1 +; EPILOG-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[LATCH_EXIT_EPILOG_LCSSA:%.*]], label [[HEADER_EPIL]], !llvm.loop !5 +; EPILOG: latch_exit.epilog-lcssa: +; EPILOG-NEXT: br label [[LATCH_EXIT]] +; EPILOG: latch_exit: +; EPILOG-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCH_EXIT_UNR_LCSSA]] ], [ [[ADD_EPIL]], [[LATCH_EXIT_EPILOG_LCSSA]] ] +; EPILOG-NEXT: ret i32 [[SUM_0_LCSSA]] +; EPILOG: for.exit2.loopexit: +; EPILOG-NEXT: [[RETVAL_PH:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK]] ], [ [[SUM_02]], [[HEADER]] ], [ [[ADD]], [[LATCH]] ], [ 42, [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1:%.*]], [[LATCH_1:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_2:%.*]] ], [ [[ADD_2:%.*]], [[LATCH_2:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_3:%.*]] ], [ [[ADD_3:%.*]], [[LATCH_3:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_4:%.*]] ], [ [[ADD_4:%.*]], [[LATCH_4:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_5:%.*]] ], [ [[ADD_5:%.*]], [[LATCH_5:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_6:%.*]] ], [ [[ADD_6:%.*]], [[LATCH_6:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_7:%.*]] ] +; EPILOG-NEXT: br label [[FOR_EXIT2:%.*]] +; EPILOG: for.exit2.loopexit2: +; EPILOG-NEXT: [[RETVAL_PH3:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK_EPIL]] ], [ [[SUM_02_EPIL]], [[HEADER_EPIL]] ] +; EPILOG-NEXT: br label [[FOR_EXIT2]] +; EPILOG: for.exit2: +; EPILOG-NEXT: [[RETVAL:%.*]] = phi i32 [ [[RETVAL_PH]], [[FOR_EXIT2_LOOPEXIT]] ], [ [[RETVAL_PH3]], [[FOR_EXIT2_LOOPEXIT2]] ] +; EPILOG-NEXT: br i1 [[COND:%.*]], label [[EXIT_TRUE:%.*]], label [[EXIT_FALSE:%.*]] +; EPILOG: exit_true: +; EPILOG-NEXT: ret i32 [[RETVAL]] +; EPILOG: exit_false: +; EPILOG-NEXT: [[ADDX:%.*]] = add i32 [[RETVAL]], [[X:%.*]] +; EPILOG-NEXT: ret i32 [[ADDX]] +; EPILOG: for.exiting_block.1: +; EPILOG-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_1]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_1]] +; EPILOG: latch.1: +; EPILOG-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]] +; EPILOG-NEXT: [[LOAD_1:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 +; EPILOG-NEXT: [[ADD_1]] = add nsw i32 [[LOAD_1]], [[ADD]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = or i64 [[INDVARS_IV]], 2 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_2]] +; EPILOG: for.exiting_block.2: +; EPILOG-NEXT: [[CMP_2:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_2]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_2]] +; EPILOG: latch.2: +; EPILOG-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]] +; EPILOG-NEXT: [[LOAD_2:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 +; EPILOG-NEXT: [[ADD_2]] = add nsw i32 [[LOAD_2]], [[ADD_1]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = or i64 [[INDVARS_IV]], 3 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_3]] +; EPILOG: for.exiting_block.3: +; EPILOG-NEXT: [[CMP_3:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_3]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_3]] +; EPILOG: latch.3: +; EPILOG-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]] +; EPILOG-NEXT: [[LOAD_3:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 +; EPILOG-NEXT: [[ADD_3]] = add nsw i32 [[LOAD_3]], [[ADD_2]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = or i64 [[INDVARS_IV]], 4 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_4]] +; EPILOG: for.exiting_block.4: +; EPILOG-NEXT: [[CMP_4:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_4]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_4]] +; EPILOG: latch.4: +; EPILOG-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]] +; EPILOG-NEXT: [[LOAD_4:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 +; EPILOG-NEXT: [[ADD_4]] = add nsw i32 [[LOAD_4]], [[ADD_3]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_4:%.*]] = or i64 [[INDVARS_IV]], 5 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_5]] +; EPILOG: for.exiting_block.5: +; EPILOG-NEXT: [[CMP_5:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_5]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_5]] +; EPILOG: latch.5: +; EPILOG-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]] +; EPILOG-NEXT: [[LOAD_5:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 +; EPILOG-NEXT: [[ADD_5]] = add nsw i32 [[LOAD_5]], [[ADD_4]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_5:%.*]] = or i64 [[INDVARS_IV]], 6 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_6]] +; EPILOG: for.exiting_block.6: +; EPILOG-NEXT: [[CMP_6:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_6]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_6]] +; EPILOG: latch.6: +; EPILOG-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]] +; EPILOG-NEXT: [[LOAD_6:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 +; EPILOG-NEXT: [[ADD_6]] = add nsw i32 [[LOAD_6]], [[ADD_5]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_6:%.*]] = or i64 [[INDVARS_IV]], 7 +; EPILOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_7]] +; EPILOG: for.exiting_block.7: +; EPILOG-NEXT: [[CMP_7:%.*]] = icmp eq i64 [[N]], 42 +; EPILOG-NEXT: br i1 [[CMP_7]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_7]] +; EPILOG: latch.7: +; EPILOG-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]] +; EPILOG-NEXT: [[LOAD_7:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 +; EPILOG-NEXT: [[ADD_7]] = add nsw i32 [[LOAD_7]], [[ADD_6]] +; EPILOG-NEXT: [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8 +; EPILOG-NEXT: [[NITER_NSUB_7]] = add i64 [[NITER]], -8 +; EPILOG-NEXT: [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0 +; EPILOG-NEXT: br i1 [[NITER_NCMP_7]], label [[LATCH_EXIT_UNR_LCSSA_LOOPEXIT]], label [[HEADER]] +; +; PROLOG-LABEL: @test6( +; PROLOG-NEXT: entry: +; PROLOG-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 +; PROLOG-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 7 +; PROLOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0 +; PROLOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[HEADER_PROL_LOOPEXIT:%.*]], label [[HEADER_PROL_PREHEADER:%.*]] +; PROLOG: header.prol.preheader: +; PROLOG-NEXT: br label [[HEADER_PROL:%.*]] +; PROLOG: header.prol: +; PROLOG-NEXT: [[INDVARS_IV_PROL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PROL:%.*]], [[LATCH_PROL:%.*]] ], [ 0, [[HEADER_PROL_PREHEADER]] ] +; PROLOG-NEXT: [[SUM_02_PROL:%.*]] = phi i32 [ [[ADD_PROL:%.*]], [[LATCH_PROL]] ], [ 0, [[HEADER_PROL_PREHEADER]] ] +; PROLOG-NEXT: [[PROL_ITER:%.*]] = phi i64 [ [[PROL_ITER_SUB:%.*]], [[LATCH_PROL]] ], [ [[XTRAITER]], [[HEADER_PROL_PREHEADER]] ] +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT1:%.*]], label [[FOR_EXITING_BLOCK_PROL:%.*]] +; PROLOG: for.exiting_block.prol: +; PROLOG-NEXT: [[CMP_PROL:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_PROL]], label [[FOR_EXIT2_LOOPEXIT1]], label [[LATCH_PROL]] +; PROLOG: latch.prol: +; PROLOG-NEXT: [[ARRAYIDX_PROL:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV_PROL]] +; PROLOG-NEXT: [[LOAD_PROL:%.*]] = load i32, i32* [[ARRAYIDX_PROL]], align 4 +; PROLOG-NEXT: [[ADD_PROL]] = add nsw i32 [[LOAD_PROL]], [[SUM_02_PROL]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_PROL]] = add i64 [[INDVARS_IV_PROL]], 1 +; PROLOG-NEXT: [[PROL_ITER_SUB]] = add i64 [[PROL_ITER]], -1 +; PROLOG-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_SUB]], 0 +; PROLOG-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], label [[HEADER_PROL]], !llvm.loop !5 +; PROLOG: header.prol.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[HEADER_PROL_LOOPEXIT]] +; PROLOG: header.prol.loopexit: +; PROLOG-NEXT: [[SUM_0_LCSSA_UNR:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[ADD_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 +; PROLOG-NEXT: br i1 [[TMP1]], label [[LATCH_EXIT:%.*]], label [[ENTRY_NEW:%.*]] +; PROLOG: entry.new: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_UNR]], [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ] +; PROLOG-NEXT: [[SUM_02:%.*]] = phi i32 [ [[SUM_02_UNR]], [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ] +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT:%.*]], label [[FOR_EXITING_BLOCK:%.*]] +; PROLOG: for.exiting_block: +; PROLOG-NEXT: [[CMP:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH:%.*]] +; PROLOG: latch: +; PROLOG-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] +; PROLOG-NEXT: [[LOAD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; PROLOG-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD]], [[SUM_02]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT:%.*]] = add i64 [[INDVARS_IV]], 1 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_1:%.*]] +; PROLOG: latch_exit.unr-lcssa: +; PROLOG-NEXT: br label [[LATCH_EXIT]] +; PROLOG: latch_exit: +; PROLOG-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_UNR]], [[HEADER_PROL_LOOPEXIT]] ], [ [[ADD_7]], [[LATCH_EXIT_UNR_LCSSA:%.*]] ] +; PROLOG-NEXT: ret i32 [[SUM_0_LCSSA]] +; PROLOG: for.exit2.loopexit: +; PROLOG-NEXT: [[RETVAL_PH:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK]] ], [ [[SUM_02]], [[HEADER]] ], [ [[ADD]], [[LATCH]] ], [ 42, [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1:%.*]], [[LATCH_1:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_2:%.*]] ], [ [[ADD_2:%.*]], [[LATCH_2:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_3:%.*]] ], [ [[ADD_3:%.*]], [[LATCH_3:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_4:%.*]] ], [ [[ADD_4:%.*]], [[LATCH_4:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_5:%.*]] ], [ [[ADD_5:%.*]], [[LATCH_5:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_6:%.*]] ], [ [[ADD_6:%.*]], [[LATCH_6:%.*]] ], [ 42, [[FOR_EXITING_BLOCK_7:%.*]] ] +; PROLOG-NEXT: br label [[FOR_EXIT2:%.*]] +; PROLOG: for.exit2.loopexit1: +; PROLOG-NEXT: [[RETVAL_PH2:%.*]] = phi i32 [ 42, [[FOR_EXITING_BLOCK_PROL]] ], [ [[SUM_02_PROL]], [[HEADER_PROL]] ] +; PROLOG-NEXT: br label [[FOR_EXIT2]] +; PROLOG: for.exit2: +; PROLOG-NEXT: [[RETVAL:%.*]] = phi i32 [ [[RETVAL_PH]], [[FOR_EXIT2_LOOPEXIT]] ], [ [[RETVAL_PH2]], [[FOR_EXIT2_LOOPEXIT1]] ] +; PROLOG-NEXT: br i1 [[COND:%.*]], label [[EXIT_TRUE:%.*]], label [[EXIT_FALSE:%.*]] +; PROLOG: exit_true: +; PROLOG-NEXT: ret i32 [[RETVAL]] +; PROLOG: exit_false: +; PROLOG-NEXT: [[ADDX:%.*]] = add i32 [[RETVAL]], [[X:%.*]] +; PROLOG-NEXT: ret i32 [[ADDX]] +; PROLOG: for.exiting_block.1: +; PROLOG-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_1]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_1]] +; PROLOG: latch.1: +; PROLOG-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]] +; PROLOG-NEXT: [[LOAD_1:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 +; PROLOG-NEXT: [[ADD_1]] = add nsw i32 [[LOAD_1]], [[ADD]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = add i64 [[INDVARS_IV]], 2 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_2]] +; PROLOG: for.exiting_block.2: +; PROLOG-NEXT: [[CMP_2:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_2]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_2]] +; PROLOG: latch.2: +; PROLOG-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]] +; PROLOG-NEXT: [[LOAD_2:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 +; PROLOG-NEXT: [[ADD_2]] = add nsw i32 [[LOAD_2]], [[ADD_1]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = add i64 [[INDVARS_IV]], 3 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_3]] +; PROLOG: for.exiting_block.3: +; PROLOG-NEXT: [[CMP_3:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_3]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_3]] +; PROLOG: latch.3: +; PROLOG-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]] +; PROLOG-NEXT: [[LOAD_3:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 +; PROLOG-NEXT: [[ADD_3]] = add nsw i32 [[LOAD_3]], [[ADD_2]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_3:%.*]] = add i64 [[INDVARS_IV]], 4 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_4]] +; PROLOG: for.exiting_block.4: +; PROLOG-NEXT: [[CMP_4:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_4]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_4]] +; PROLOG: latch.4: +; PROLOG-NEXT: [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]] +; PROLOG-NEXT: [[LOAD_4:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4 +; PROLOG-NEXT: [[ADD_4]] = add nsw i32 [[LOAD_4]], [[ADD_3]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_4:%.*]] = add i64 [[INDVARS_IV]], 5 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_5]] +; PROLOG: for.exiting_block.5: +; PROLOG-NEXT: [[CMP_5:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_5]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_5]] +; PROLOG: latch.5: +; PROLOG-NEXT: [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]] +; PROLOG-NEXT: [[LOAD_5:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4 +; PROLOG-NEXT: [[ADD_5]] = add nsw i32 [[LOAD_5]], [[ADD_4]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_5:%.*]] = add i64 [[INDVARS_IV]], 6 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_6]] +; PROLOG: for.exiting_block.6: +; PROLOG-NEXT: [[CMP_6:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_6]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_6]] +; PROLOG: latch.6: +; PROLOG-NEXT: [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]] +; PROLOG-NEXT: [[LOAD_6:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4 +; PROLOG-NEXT: [[ADD_6]] = add nsw i32 [[LOAD_6]], [[ADD_5]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_6:%.*]] = add i64 [[INDVARS_IV]], 7 +; PROLOG-NEXT: br i1 false, label [[FOR_EXIT2_LOOPEXIT]], label [[FOR_EXITING_BLOCK_7]] +; PROLOG: for.exiting_block.7: +; PROLOG-NEXT: [[CMP_7:%.*]] = icmp eq i64 [[N]], 42 +; PROLOG-NEXT: br i1 [[CMP_7]], label [[FOR_EXIT2_LOOPEXIT]], label [[LATCH_7]] +; PROLOG: latch.7: +; PROLOG-NEXT: [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]] +; PROLOG-NEXT: [[LOAD_7:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4 +; PROLOG-NEXT: [[ADD_7]] = add nsw i32 [[LOAD_7]], [[ADD_6]] +; PROLOG-NEXT: [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8 +; PROLOG-NEXT: [[EXITCOND_7:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_7]], [[N]] +; PROLOG-NEXT: br i1 [[EXITCOND_7]], label [[LATCH_EXIT_UNR_LCSSA]], label [[HEADER]] +; -; PROLOG: test6( -; PROLOG: for.exit2.loopexit: -; PROLOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %latch ], [ 42, %for.exiting_block.1 ], [ %add.1, %latch.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %latch.2 ], -; PROLOG-NEXT: br label %for.exit2 -; PROLOG: for.exit2.loopexit1: -; PROLOG-NEXT: %retval.ph2 = phi i32 [ 42, %for.exiting_block.prol ], [ %sum.02.prol, %header.prol ] -; PROLOG-NEXT: br label %for.exit2 -; PROLOG: for.exit2: -; PROLOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph2, %for.exit2.loopexit1 ] -; PROLOG-NEXT: br i1 %cond, label %exit_true, label %exit_false -; PROLOG: latch.7: -; PROLOG: %indvars.iv.next.7 = add i64 %indvars.iv, 8 entry: br label %header @@ -492,8 +2144,8 @@ br i1 false, label %for.exit2, label %for.exiting_block for.exiting_block: - %cmp = icmp eq i64 %n, 42 - br i1 %cmp, label %for.exit2, label %latch + %cmp = icmp eq i64 %n, 42 + br i1 %cmp, label %for.exit2, label %latch latch: %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv @@ -521,15 +2173,204 @@ ; test when value in exit block does not have VMap. define i32 @test7(i32 %arg, i32 %arg1, i32 %arg2) { -; EPILOG-NO-IC: test7( -; EPILOG-NO-IC: loopexit1.loopexit: -; EPILOG-NO-IC-NEXT: %sext3.ph = phi i32 [ %shft, %header ], [ %shft, %latch ], [ %shft, %latch.1 ], [ %shft, %latch.2 ], [ %shft, %latch.3 ], [ %shft, %latch.4 ], [ %shft, %latch.5 ], [ %shft, %latch.6 ] -; EPILOG-NO-IC-NEXT: br label %loopexit1 -; EPILOG-NO-IC: loopexit1.loopexit1: -; EPILOG-NO-IC-NEXT: %sext3.ph2 = phi i32 [ %shft, %header.epil ] -; EPILOG-NO-IC-NEXT: br label %loopexit1 -; EPILOG-NO-IC: loopexit1: -; EPILOG-NO-IC-NEXT: %sext3 = phi i32 [ %sext3.ph, %loopexit1.loopexit ], [ %sext3.ph2, %loopexit1.loopexit1 ] +; EPILOG-NO-IC-LABEL: @test7( +; EPILOG-NO-IC-NEXT: bb: +; EPILOG-NO-IC-NEXT: [[I:%.*]] = icmp slt i32 undef, 2 +; EPILOG-NO-IC-NEXT: [[SEXT:%.*]] = sext i32 undef to i64 +; EPILOG-NO-IC-NEXT: [[SHFT:%.*]] = ashr exact i32 [[ARG:%.*]], 16 +; EPILOG-NO-IC-NEXT: br i1 [[I]], label [[LOOPEXIT2:%.*]], label [[PREHEADER:%.*]] +; EPILOG-NO-IC: preheader: +; EPILOG-NO-IC-NEXT: [[TMP0:%.*]] = add i64 [[SEXT]], -1 +; EPILOG-NO-IC-NEXT: [[TMP1:%.*]] = add nsw i64 [[SEXT]], -2 +; EPILOG-NO-IC-NEXT: [[XTRAITER:%.*]] = and i64 [[TMP0]], 7 +; EPILOG-NO-IC-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7 +; EPILOG-NO-IC-NEXT: br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[PREHEADER_NEW:%.*]] +; EPILOG-NO-IC: preheader.new: +; EPILOG-NO-IC-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[TMP0]], [[XTRAITER]] +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[I6:%.*]] = phi i64 [ 1, [[PREHEADER_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7:%.*]] ] +; EPILOG-NO-IC-NEXT: [[NITER:%.*]] = phi i64 [ [[UNROLL_ITER]], [[PREHEADER_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT:%.*]], label [[LATCH:%.*]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[I6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB:%.*]] = sub i64 [[NITER]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_1:%.*]] +; EPILOG-NO-IC: latchexit.unr-lcssa.loopexit: +; EPILOG-NO-IC-NEXT: [[I6_UNR_PH:%.*]] = phi i64 [ [[ADD_7]], [[LATCH_7]] ] +; EPILOG-NO-IC-NEXT: br label [[LATCHEXIT_UNR_LCSSA]] +; EPILOG-NO-IC: latchexit.unr-lcssa: +; EPILOG-NO-IC-NEXT: [[I6_UNR:%.*]] = phi i64 [ 1, [[PREHEADER]] ], [ [[I6_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]] ] +; EPILOG-NO-IC-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCHEXIT:%.*]] +; EPILOG-NO-IC: header.epil.preheader: +; EPILOG-NO-IC-NEXT: br label [[HEADER_EPIL:%.*]] +; EPILOG-NO-IC: header.epil: +; EPILOG-NO-IC-NEXT: [[I6_EPIL:%.*]] = phi i64 [ [[I6_UNR]], [[HEADER_EPIL_PREHEADER]] ], [ [[ADD_EPIL:%.*]], [[LATCH_EPIL:%.*]] ] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ [[XTRAITER]], [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[LATCH_EPIL]] ] +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT1:%.*]], label [[LATCH_EPIL]] +; EPILOG-NO-IC: latch.epil: +; EPILOG-NO-IC-NEXT: [[ADD_EPIL]] = add nuw nsw i64 [[I6_EPIL]], 1 +; EPILOG-NO-IC-NEXT: [[I9_EPIL:%.*]] = icmp slt i64 [[ADD_EPIL]], [[SEXT]] +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_SUB]] = sub i64 [[EPIL_ITER]], 1 +; EPILOG-NO-IC-NEXT: [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], !llvm.loop !6 +; EPILOG-NO-IC: latchexit.epilog-lcssa: +; EPILOG-NO-IC-NEXT: br label [[LATCHEXIT]] +; EPILOG-NO-IC: latchexit: +; EPILOG-NO-IC-NEXT: unreachable +; EPILOG-NO-IC: loopexit2: +; EPILOG-NO-IC-NEXT: ret i32 [[SHFT]] +; EPILOG-NO-IC: loopexit1.loopexit: +; EPILOG-NO-IC-NEXT: [[SEXT3_PH:%.*]] = phi i32 [ [[SHFT]], [[HEADER]] ], [ [[SHFT]], [[LATCH]] ], [ [[SHFT]], [[LATCH_1]] ], [ [[SHFT]], [[LATCH_2:%.*]] ], [ [[SHFT]], [[LATCH_3:%.*]] ], [ [[SHFT]], [[LATCH_4:%.*]] ], [ [[SHFT]], [[LATCH_5:%.*]] ], [ [[SHFT]], [[LATCH_6:%.*]] ] +; EPILOG-NO-IC-NEXT: br label [[LOOPEXIT1:%.*]] +; EPILOG-NO-IC: loopexit1.loopexit1: +; EPILOG-NO-IC-NEXT: [[SEXT3_PH2:%.*]] = phi i32 [ [[SHFT]], [[HEADER_EPIL]] ] +; EPILOG-NO-IC-NEXT: br label [[LOOPEXIT1]] +; EPILOG-NO-IC: loopexit1: +; EPILOG-NO-IC-NEXT: [[SEXT3:%.*]] = phi i32 [ [[SEXT3_PH]], [[LOOPEXIT1_LOOPEXIT]] ], [ [[SEXT3_PH2]], [[LOOPEXIT1_LOOPEXIT1]] ] +; EPILOG-NO-IC-NEXT: ret i32 [[SEXT3]] +; EPILOG-NO-IC: latch.1: +; EPILOG-NO-IC-NEXT: [[ADD_1:%.*]] = add nuw nsw i64 [[ADD]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_1:%.*]] = sub i64 [[NITER_NSUB]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_2]] +; EPILOG-NO-IC: latch.2: +; EPILOG-NO-IC-NEXT: [[ADD_2:%.*]] = add nuw nsw i64 [[ADD_1]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_2:%.*]] = sub i64 [[NITER_NSUB_1]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_3]] +; EPILOG-NO-IC: latch.3: +; EPILOG-NO-IC-NEXT: [[ADD_3:%.*]] = add nuw nsw i64 [[ADD_2]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_3:%.*]] = sub i64 [[NITER_NSUB_2]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_4]] +; EPILOG-NO-IC: latch.4: +; EPILOG-NO-IC-NEXT: [[ADD_4:%.*]] = add nuw nsw i64 [[ADD_3]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_4:%.*]] = sub i64 [[NITER_NSUB_3]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_5]] +; EPILOG-NO-IC: latch.5: +; EPILOG-NO-IC-NEXT: [[ADD_5:%.*]] = add nuw nsw i64 [[ADD_4]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_5:%.*]] = sub i64 [[NITER_NSUB_4]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_6]] +; EPILOG-NO-IC: latch.6: +; EPILOG-NO-IC-NEXT: [[ADD_6:%.*]] = add nuw nsw i64 [[ADD_5]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_6:%.*]] = sub i64 [[NITER_NSUB_5]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_7]] +; EPILOG-NO-IC: latch.7: +; EPILOG-NO-IC-NEXT: [[ADD_7]] = add nuw nsw i64 [[ADD_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NSUB_7]] = sub i64 [[NITER_NSUB_6]], 1 +; EPILOG-NO-IC-NEXT: [[NITER_NCMP_7:%.*]] = icmp ne i64 [[NITER_NSUB_7]], 0 +; EPILOG-NO-IC-NEXT: br i1 [[NITER_NCMP_7]], label [[HEADER]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] +; +; EPILOG-LABEL: @test7( +; EPILOG-NEXT: bb: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT2:%.*]], label [[PREHEADER:%.*]] +; EPILOG: preheader: +; EPILOG-NEXT: br i1 false, label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[PREHEADER_NEW:%.*]] +; EPILOG: preheader.new: +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[NITER:%.*]] = phi i64 [ -8, [[PREHEADER_NEW]] ], [ [[NITER_NSUB_7:%.*]], [[LATCH_7:%.*]] ] +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT:%.*]], label [[LATCH:%.*]] +; EPILOG: latch: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_1:%.*]] +; EPILOG: latchexit.unr-lcssa.loopexit: +; EPILOG-NEXT: br label [[LATCHEXIT_UNR_LCSSA]] +; EPILOG: latchexit.unr-lcssa: +; EPILOG-NEXT: br i1 true, label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCHEXIT:%.*]] +; EPILOG: header.epil.preheader: +; EPILOG-NEXT: br label [[HEADER_EPIL:%.*]] +; EPILOG: header.epil: +; EPILOG-NEXT: [[EPIL_ITER:%.*]] = phi i64 [ 7, [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_SUB:%.*]], [[LATCH_EPIL:%.*]] ] +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT1:%.*]], label [[LATCH_EPIL]] +; EPILOG: latch.epil: +; EPILOG-NEXT: [[EPIL_ITER_SUB]] = add i64 [[EPIL_ITER]], -1 +; EPILOG-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_SUB]], 0 +; EPILOG-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], label [[HEADER_EPIL]], !llvm.loop !6 +; EPILOG: latchexit.epilog-lcssa: +; EPILOG-NEXT: br label [[LATCHEXIT]] +; EPILOG: latchexit: +; EPILOG-NEXT: unreachable +; EPILOG: loopexit2: +; EPILOG-NEXT: ret i32 undef +; EPILOG: loopexit1.loopexit: +; EPILOG-NEXT: br label [[LOOPEXIT1:%.*]] +; EPILOG: loopexit1.loopexit1: +; EPILOG-NEXT: br label [[LOOPEXIT1]] +; EPILOG: loopexit1: +; EPILOG-NEXT: ret i32 undef +; EPILOG: latch.1: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_2:%.*]] +; EPILOG: latch.2: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_3:%.*]] +; EPILOG: latch.3: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_4:%.*]] +; EPILOG: latch.4: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_5:%.*]] +; EPILOG: latch.5: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_6:%.*]] +; EPILOG: latch.6: +; EPILOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_7]] +; EPILOG: latch.7: +; EPILOG-NEXT: [[NITER_NSUB_7]] = add i64 [[NITER]], -8 +; EPILOG-NEXT: [[NITER_NCMP_7_NOT:%.*]] = icmp eq i64 [[NITER_NSUB_7]], 0 +; EPILOG-NEXT: br i1 [[NITER_NCMP_7_NOT]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]] +; +; PROLOG-LABEL: @test7( +; PROLOG-NEXT: bb: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT2:%.*]], label [[PREHEADER:%.*]] +; PROLOG: preheader: +; PROLOG-NEXT: br i1 true, label [[HEADER_PROL_PREHEADER:%.*]], label [[HEADER_PROL_LOOPEXIT:%.*]] +; PROLOG: header.prol.preheader: +; PROLOG-NEXT: br label [[HEADER_PROL:%.*]] +; PROLOG: header.prol: +; PROLOG-NEXT: [[I6_PROL:%.*]] = phi i64 [ 1, [[HEADER_PROL_PREHEADER]] ], [ [[ADD_PROL:%.*]], [[LATCH_PROL:%.*]] ] +; PROLOG-NEXT: [[PROL_ITER:%.*]] = phi i64 [ 7, [[HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_SUB:%.*]], [[LATCH_PROL]] ] +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT1:%.*]], label [[LATCH_PROL]] +; PROLOG: latch.prol: +; PROLOG-NEXT: [[ADD_PROL]] = add nuw nsw i64 [[I6_PROL]], 1 +; PROLOG-NEXT: [[PROL_ITER_SUB]] = add i64 [[PROL_ITER]], -1 +; PROLOG-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_SUB]], 0 +; PROLOG-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], label [[HEADER_PROL]], !llvm.loop !6 +; PROLOG: header.prol.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[HEADER_PROL_LOOPEXIT]] +; PROLOG: header.prol.loopexit: +; PROLOG-NEXT: [[I6_UNR:%.*]] = phi i64 [ 1, [[PREHEADER]] ], [ [[ADD_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: br i1 false, label [[LATCHEXIT:%.*]], label [[PREHEADER_NEW:%.*]] +; PROLOG: preheader.new: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[I6:%.*]] = phi i64 [ [[I6_UNR]], [[PREHEADER_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7:%.*]] ] +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT:%.*]], label [[LATCH:%.*]] +; PROLOG: latch: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_1:%.*]] +; PROLOG: latchexit.unr-lcssa: +; PROLOG-NEXT: br label [[LATCHEXIT]] +; PROLOG: latchexit: +; PROLOG-NEXT: unreachable +; PROLOG: loopexit2: +; PROLOG-NEXT: ret i32 undef +; PROLOG: loopexit1.loopexit: +; PROLOG-NEXT: br label [[LOOPEXIT1:%.*]] +; PROLOG: loopexit1.loopexit1: +; PROLOG-NEXT: br label [[LOOPEXIT1]] +; PROLOG: loopexit1: +; PROLOG-NEXT: ret i32 undef +; PROLOG: latch.1: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_2:%.*]] +; PROLOG: latch.2: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_3:%.*]] +; PROLOG: latch.3: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_4:%.*]] +; PROLOG: latch.4: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_5:%.*]] +; PROLOG: latch.5: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_6:%.*]] +; PROLOG: latch.6: +; PROLOG-NEXT: br i1 false, label [[LOOPEXIT1_LOOPEXIT]], label [[LATCH_7]] +; PROLOG: latch.7: +; PROLOG-NEXT: [[ADD_7]] = add nuw nsw i64 [[I6]], 8 +; PROLOG-NEXT: [[I9_7:%.*]] = icmp slt i64 [[I6]], -8 +; PROLOG-NEXT: br i1 [[I9_7]], label [[HEADER]], label [[LATCHEXIT_UNR_LCSSA:%.*]] +; bb: %i = icmp slt i32 undef, 2 %sext = sext i32 undef to i64 @@ -552,7 +2393,7 @@ unreachable loopexit2: ; preds = %bb2 - ret i32 %shft + ret i32 %shft loopexit1: ; preds = %header %sext3 = phi i32 [ %shft, %header ] @@ -569,20 +2410,103 @@ ; The outer loop header is the preheader for the inner loop and the inner header ; branches back to the outer loop. define void @test8() { -; EPILOG: test8( -; EPILOG-NOT: niter +; EPILOG-NO-IC-LABEL: @test8( +; EPILOG-NO-IC-NEXT: bb: +; EPILOG-NO-IC-NEXT: br label [[OUTERLOOP:%.*]] +; EPILOG-NO-IC: outerloop.loopexit: +; EPILOG-NO-IC-NEXT: br label [[OUTERLOOP]] +; EPILOG-NO-IC: outerloop: +; EPILOG-NO-IC-NEXT: [[I:%.*]] = phi i64 [ 3, [[BB:%.*]] ], [ 0, [[OUTERLOOP_LOOPEXIT:%.*]] ] +; EPILOG-NO-IC-NEXT: br label [[INNERH:%.*]] +; EPILOG-NO-IC: innerH: +; EPILOG-NO-IC-NEXT: [[I3:%.*]] = phi i64 [ [[I4:%.*]], [[LATCH:%.*]] ], [ [[I]], [[OUTERLOOP]] ] +; EPILOG-NO-IC-NEXT: [[I4]] = add nuw nsw i64 [[I3]], 1 +; EPILOG-NO-IC-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT]], label [[LATCH]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[I6:%.*]] = icmp ult i64 [[I4]], 100 +; EPILOG-NO-IC-NEXT: br i1 [[I6]], label [[INNERH]], label [[EXIT:%.*]] +; EPILOG-NO-IC: exit: +; EPILOG-NO-IC-NEXT: ret void +; +; EPILOG-LABEL: @test8( +; EPILOG-NEXT: bb: +; EPILOG-NEXT: br label [[OUTERLOOP:%.*]] +; EPILOG: outerloop.loopexit: +; EPILOG-NEXT: br label [[OUTERLOOP]] +; EPILOG: outerloop: +; EPILOG-NEXT: [[I:%.*]] = phi i64 [ 3, [[BB:%.*]] ], [ 0, [[OUTERLOOP_LOOPEXIT:%.*]] ] +; EPILOG-NEXT: br label [[INNERH:%.*]] +; EPILOG: innerH: +; EPILOG-NEXT: [[I3:%.*]] = phi i64 [ [[I4:%.*]], [[LATCH:%.*]] ], [ [[I]], [[OUTERLOOP]] ] +; EPILOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT]], label [[LATCH]] +; EPILOG: latch: +; EPILOG-NEXT: [[I4]] = add nuw nsw i64 [[I3]], 1 +; EPILOG-NEXT: [[I6:%.*]] = icmp ult i64 [[I3]], 99 +; EPILOG-NEXT: br i1 [[I6]], label [[INNERH]], label [[EXIT:%.*]] +; EPILOG: exit: +; EPILOG-NEXT: ret void +; +; PROLOG-LABEL: @test8( +; PROLOG-NEXT: bb: +; PROLOG-NEXT: br label [[OUTERLOOP:%.*]] +; PROLOG: outerloop.loopexit.loopexit: +; PROLOG-NEXT: br label [[OUTERLOOP_LOOPEXIT:%.*]] +; PROLOG: outerloop.loopexit.loopexit1: +; PROLOG-NEXT: br label [[OUTERLOOP_LOOPEXIT]] +; PROLOG: outerloop.loopexit: +; PROLOG-NEXT: br label [[OUTERLOOP]] +; PROLOG: outerloop: +; PROLOG-NEXT: [[I:%.*]] = phi i64 [ 3, [[BB:%.*]] ], [ 0, [[OUTERLOOP_LOOPEXIT]] ] +; PROLOG-NEXT: [[TMP0:%.*]] = sub nuw nsw i64 4, [[I]] +; PROLOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[TMP0]], 0 +; PROLOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[INNERH_PROL_LOOPEXIT:%.*]], label [[INNERH_PROL_PREHEADER:%.*]] +; PROLOG: innerH.prol.preheader: +; PROLOG-NEXT: br label [[INNERH_PROL:%.*]] +; PROLOG: innerH.prol: +; PROLOG-NEXT: [[I3_PROL:%.*]] = phi i64 [ [[I4_PROL:%.*]], [[LATCH_PROL:%.*]] ], [ [[I]], [[INNERH_PROL_PREHEADER]] ] +; PROLOG-NEXT: [[PROL_ITER:%.*]] = phi i64 [ [[PROL_ITER_SUB:%.*]], [[LATCH_PROL]] ], [ [[TMP0]], [[INNERH_PROL_PREHEADER]] ] +; PROLOG-NEXT: [[I4_PROL]] = add nuw nsw i64 [[I3_PROL]], 1 +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT1:%.*]], label [[LATCH_PROL]] +; PROLOG: latch.prol: +; PROLOG-NEXT: [[PROL_ITER_SUB]] = add i64 [[PROL_ITER]], -1 +; PROLOG-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_SUB]], 0 +; PROLOG-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label [[INNERH_PROL_LOOPEXIT_UNR_LCSSA:%.*]], label [[INNERH_PROL]], !llvm.loop !7 +; PROLOG: innerH.prol.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[INNERH_PROL_LOOPEXIT]] +; PROLOG: innerH.prol.loopexit: +; PROLOG-NEXT: [[I3_UNR:%.*]] = phi i64 [ [[I]], [[OUTERLOOP]] ], [ [[I4_PROL]], [[INNERH_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: br i1 false, label [[EXIT_LOOPEXIT:%.*]], label [[OUTERLOOP_NEW:%.*]] +; PROLOG: outerloop.new: +; PROLOG-NEXT: br label [[INNERH:%.*]] +; PROLOG: innerH: +; PROLOG-NEXT: [[I3:%.*]] = phi i64 [ [[I3_UNR]], [[OUTERLOOP_NEW]] ], [ [[I4_7:%.*]], [[LATCH_7:%.*]] ] +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]] +; PROLOG: latch: +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT]], label [[LATCH_1:%.*]] +; PROLOG: exit.unr-lcssa: +; PROLOG-NEXT: br label [[EXIT:%.*]] +; PROLOG: exit.loopexit: +; PROLOG-NEXT: br label [[EXIT]] +; PROLOG: exit: +; PROLOG-NEXT: ret void +; PROLOG: latch.1: +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT]], label [[LATCH_2:%.*]] +; PROLOG: latch.2: +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT]], label [[LATCH_3:%.*]] +; PROLOG: latch.3: +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT]], label [[LATCH_4:%.*]] +; PROLOG: latch.4: +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT]], label [[LATCH_5:%.*]] +; PROLOG: latch.5: +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT]], label [[LATCH_6:%.*]] +; PROLOG: latch.6: +; PROLOG-NEXT: br i1 false, label [[OUTERLOOP_LOOPEXIT_LOOPEXIT]], label [[LATCH_7]] +; PROLOG: latch.7: +; PROLOG-NEXT: [[I4_7]] = add nuw nsw i64 [[I3]], 8 +; PROLOG-NEXT: [[I6_7:%.*]] = icmp ult i64 [[I3]], 92 +; PROLOG-NEXT: br i1 [[I6_7]], label [[INNERH]], label [[EXIT_UNR_LCSSA:%.*]] +; -; PROLOG: test8( -; PROLOG: outerloop: -; PROLOG-NEXT: phi i64 [ 3, %bb ], [ 0, %outerloop.loopexit ] -; PROLOG: %lcmp.mod = icmp eq i64 -; PROLOG-NEXT: br i1 %lcmp.mod, label %innerH.prol.loopexit, label %innerH.prol.preheader -; PROLOG: latch.6: -; PROLOG-NEXT: br i1 false, label %outerloop.loopexit.loopexit, label %latch.7 -; PROLOG: latch.7: -; PROLOG-NEXT: %i4.7 = add nuw nsw i64 %i3, 8 -; PROLOG-NEXT: %i6.7 = icmp ult i64 %i3, 92 -; PROLOG-NEXT: br i1 %i6.7, label %innerH, label %exit.unr-lcssa bb: br label %outerloop @@ -608,12 +2532,127 @@ ; a value from outer loop is used in exit block of inner loop. ; Don't create VMap entries for such values (%trip). define i8 addrspace(1)* @test9(i8* nocapture readonly %arg, i32 %n) { -; PROLOG: test9( -; PROLOG: header.prol: -; PROLOG-NEXT: %phi.prol = phi i64 [ 0, %header.prol.preheader ], [ %iv.next.prol, %latch.prol ] -; PROLOG: latch.prol: -; PROLOG-NOT: trip -; PROLOG: br i1 %prol.iter.cmp, label %header.prol.loopexit.unr-lcssa, label %header.prol +; EPILOG-NO-IC-LABEL: @test9( +; EPILOG-NO-IC-NEXT: bb: +; EPILOG-NO-IC-NEXT: br label [[OUTERLOOPHDR:%.*]] +; EPILOG-NO-IC: outerloopHdr: +; EPILOG-NO-IC-NEXT: [[TRIP:%.*]] = add i32 [[N:%.*]], -1 +; EPILOG-NO-IC-NEXT: [[OUTERCND:%.*]] = icmp slt i32 0, [[TRIP]] +; EPILOG-NO-IC-NEXT: br i1 [[OUTERCND]], label [[PREHEADER:%.*]], label [[OUTERLATCH:%.*]] +; EPILOG-NO-IC: preheader: +; EPILOG-NO-IC-NEXT: [[I4:%.*]] = zext i32 0 to i64 +; EPILOG-NO-IC-NEXT: br label [[HEADER:%.*]] +; EPILOG-NO-IC: header: +; EPILOG-NO-IC-NEXT: [[PHI:%.*]] = phi i64 [ [[I4]], [[PREHEADER]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ] +; EPILOG-NO-IC-NEXT: [[I7:%.*]] = trunc i64 [[PHI]] to i32 +; EPILOG-NO-IC-NEXT: br i1 true, label [[LATCH]], label [[INNEREXIT:%.*]] +; EPILOG-NO-IC: innerexit: +; EPILOG-NO-IC-NEXT: [[TRIP_LCSSA:%.*]] = phi i32 [ [[TRIP]], [[HEADER]] ] +; EPILOG-NO-IC-NEXT: [[I9:%.*]] = call i8 addrspace(1)* @foo(i32 [[TRIP_LCSSA]]) +; EPILOG-NO-IC-NEXT: ret i8 addrspace(1)* [[I9]] +; EPILOG-NO-IC: latch: +; EPILOG-NO-IC-NEXT: [[I11:%.*]] = add nsw i32 [[I7]], 1 +; EPILOG-NO-IC-NEXT: [[INNERCND:%.*]] = icmp slt i32 [[I11]], [[TRIP]] +; EPILOG-NO-IC-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[PHI]], 1 +; EPILOG-NO-IC-NEXT: br i1 [[INNERCND]], label [[HEADER]], label [[OUTERLATCH_LOOPEXIT:%.*]] +; EPILOG-NO-IC: outerLatch.loopexit: +; EPILOG-NO-IC-NEXT: br label [[OUTERLATCH]] +; EPILOG-NO-IC: outerLatch: +; EPILOG-NO-IC-NEXT: br label [[OUTERLOOPHDR]] +; +; EPILOG-LABEL: @test9( +; EPILOG-NEXT: bb: +; EPILOG-NEXT: br label [[OUTERLOOPHDR:%.*]] +; EPILOG: outerloopHdr: +; EPILOG-NEXT: [[TRIP:%.*]] = add i32 [[N:%.*]], -1 +; EPILOG-NEXT: [[OUTERCND:%.*]] = icmp sgt i32 [[TRIP]], 0 +; EPILOG-NEXT: br i1 [[OUTERCND]], label [[PREHEADER:%.*]], label [[OUTERLATCH:%.*]] +; EPILOG: preheader: +; EPILOG-NEXT: br label [[HEADER:%.*]] +; EPILOG: header: +; EPILOG-NEXT: [[PHI:%.*]] = phi i64 [ 0, [[PREHEADER]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ] +; EPILOG-NEXT: br i1 true, label [[LATCH]], label [[INNEREXIT:%.*]] +; EPILOG: innerexit: +; EPILOG-NEXT: ret i8 addrspace(1)* undef +; EPILOG: latch: +; EPILOG-NEXT: [[I7:%.*]] = trunc i64 [[PHI]] to i32 +; EPILOG-NEXT: [[I11:%.*]] = add nsw i32 [[I7]], 1 +; EPILOG-NEXT: [[INNERCND:%.*]] = icmp slt i32 [[I11]], [[TRIP]] +; EPILOG-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[PHI]], 1 +; EPILOG-NEXT: br i1 [[INNERCND]], label [[HEADER]], label [[OUTERLATCH_LOOPEXIT:%.*]] +; EPILOG: outerLatch.loopexit: +; EPILOG-NEXT: br label [[OUTERLATCH]] +; EPILOG: outerLatch: +; EPILOG-NEXT: br label [[OUTERLOOPHDR]] +; +; PROLOG-LABEL: @test9( +; PROLOG-NEXT: bb: +; PROLOG-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 7 +; PROLOG-NEXT: [[TMP1:%.*]] = add i32 [[N]], -2 +; PROLOG-NEXT: br label [[OUTERLOOPHDR:%.*]] +; PROLOG: outerloopHdr: +; PROLOG-NEXT: [[TRIP:%.*]] = add i32 [[N]], -1 +; PROLOG-NEXT: [[OUTERCND:%.*]] = icmp sgt i32 [[TRIP]], 0 +; PROLOG-NEXT: br i1 [[OUTERCND]], label [[PREHEADER:%.*]], label [[OUTERLATCH:%.*]] +; PROLOG: preheader: +; PROLOG-NEXT: [[XTRAITER:%.*]] = and i32 [[TMP0]], 7 +; PROLOG-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i32 [[XTRAITER]], 0 +; PROLOG-NEXT: br i1 [[LCMP_MOD_NOT]], label [[HEADER_PROL_LOOPEXIT:%.*]], label [[HEADER_PROL_PREHEADER:%.*]] +; PROLOG: header.prol.preheader: +; PROLOG-NEXT: br label [[HEADER_PROL:%.*]] +; PROLOG: header.prol: +; PROLOG-NEXT: [[PHI_PROL:%.*]] = phi i64 [ 0, [[HEADER_PROL_PREHEADER]] ], [ [[IV_NEXT_PROL:%.*]], [[LATCH_PROL:%.*]] ] +; PROLOG-NEXT: [[PROL_ITER:%.*]] = phi i32 [ [[XTRAITER]], [[HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_SUB:%.*]], [[LATCH_PROL]] ] +; PROLOG-NEXT: br i1 true, label [[LATCH_PROL]], label [[INNEREXIT_LOOPEXIT1:%.*]] +; PROLOG: latch.prol: +; PROLOG-NEXT: [[IV_NEXT_PROL]] = add nuw nsw i64 [[PHI_PROL]], 1 +; PROLOG-NEXT: [[PROL_ITER_SUB]] = add i32 [[PROL_ITER]], -1 +; PROLOG-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i32 [[PROL_ITER_SUB]], 0 +; PROLOG-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], label [[HEADER_PROL]], !llvm.loop !8 +; PROLOG: header.prol.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[HEADER_PROL_LOOPEXIT]] +; PROLOG: header.prol.loopexit: +; PROLOG-NEXT: [[PHI_UNR:%.*]] = phi i64 [ 0, [[PREHEADER]] ], [ [[IV_NEXT_PROL]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] +; PROLOG-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 7 +; PROLOG-NEXT: br i1 [[TMP2]], label [[OUTERLATCH_LOOPEXIT:%.*]], label [[PREHEADER_NEW:%.*]] +; PROLOG: preheader.new: +; PROLOG-NEXT: br label [[HEADER:%.*]] +; PROLOG: header: +; PROLOG-NEXT: [[PHI:%.*]] = phi i64 [ [[PHI_UNR]], [[PREHEADER_NEW]] ], [ [[IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ] +; PROLOG-NEXT: br i1 true, label [[LATCH:%.*]], label [[INNEREXIT_LOOPEXIT:%.*]] +; PROLOG: innerexit.loopexit: +; PROLOG-NEXT: br label [[INNEREXIT:%.*]] +; PROLOG: innerexit.loopexit1: +; PROLOG-NEXT: br label [[INNEREXIT]] +; PROLOG: innerexit: +; PROLOG-NEXT: ret i8 addrspace(1)* undef +; PROLOG: latch: +; PROLOG-NEXT: br i1 true, label [[LATCH_1:%.*]], label [[INNEREXIT_LOOPEXIT]] +; PROLOG: outerLatch.loopexit.unr-lcssa: +; PROLOG-NEXT: br label [[OUTERLATCH_LOOPEXIT]] +; PROLOG: outerLatch.loopexit: +; PROLOG-NEXT: br label [[OUTERLATCH]] +; PROLOG: outerLatch: +; PROLOG-NEXT: br label [[OUTERLOOPHDR]] +; PROLOG: latch.1: +; PROLOG-NEXT: br i1 true, label [[LATCH_2:%.*]], label [[INNEREXIT_LOOPEXIT]] +; PROLOG: latch.2: +; PROLOG-NEXT: br i1 true, label [[LATCH_3:%.*]], label [[INNEREXIT_LOOPEXIT]] +; PROLOG: latch.3: +; PROLOG-NEXT: br i1 true, label [[LATCH_4:%.*]], label [[INNEREXIT_LOOPEXIT]] +; PROLOG: latch.4: +; PROLOG-NEXT: br i1 true, label [[LATCH_5:%.*]], label [[INNEREXIT_LOOPEXIT]] +; PROLOG: latch.5: +; PROLOG-NEXT: br i1 true, label [[LATCH_6:%.*]], label [[INNEREXIT_LOOPEXIT]] +; PROLOG: latch.6: +; PROLOG-NEXT: br i1 true, label [[LATCH_7]], label [[INNEREXIT_LOOPEXIT]] +; PROLOG: latch.7: +; PROLOG-NEXT: [[TMP3:%.*]] = trunc i64 [[PHI]] to i32 +; PROLOG-NEXT: [[I11_7:%.*]] = add i32 [[TMP3]], 8 +; PROLOG-NEXT: [[INNERCND_7:%.*]] = icmp slt i32 [[I11_7]], [[TRIP]] +; PROLOG-NEXT: [[IV_NEXT_7]] = add nuw nsw i64 [[PHI]], 8 +; PROLOG-NEXT: br i1 [[INNERCND_7]], label [[HEADER]], label [[OUTERLATCH_LOOPEXIT_UNR_LCSSA:%.*]] +; bb: br label %outerloopHdr diff --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll --- a/llvm/test/Transforms/PGOProfile/chr.ll +++ b/llvm/test/Transforms/PGOProfile/chr.ll @@ -36,15 +36,15 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 -; CHECK-NEXT: br i1 [[TMP4]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP3]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB1_NONCHR]] ; CHECK: bb1.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 ; CHECK: bb2.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB3]] @@ -109,22 +109,22 @@ ; CHECK-NEXT: br label [[BB5:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 -; CHECK-NEXT: br i1 [[TMP4]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP3]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB1_NONCHR]] ; CHECK: bb1.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB2_NONCHR:%.*]], label [[BB3_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB2_NONCHR:%.*]], label [[BB3_NONCHR:%.*]], !prof !16 ; CHECK: bb2.nonchr: ; CHECK-NEXT: call void @bar() ; CHECK-NEXT: br label [[BB3_NONCHR]] ; CHECK: bb3.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 4 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: br i1 [[TMP8]], label [[BB5]], label [[BB4_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 4 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: br i1 [[TMP7]], label [[BB5]], label [[BB4_NONCHR:%.*]], !prof !16 ; CHECK: bb4.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB5]] @@ -195,16 +195,16 @@ ; CHECK-NEXT: br label [[BB4:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 -; CHECK-NEXT: br i1 [[TMP4]], label [[BB4]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP3]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB4]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB2_NONCHR:%.*]], label [[BB1_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB2_NONCHR:%.*]], label [[BB1_NONCHR:%.*]], !prof !16 ; CHECK: bb2.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: br i1 [[TMP8]], label [[BB4]], label [[BB3_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: br i1 [[TMP7]], label [[BB4]], label [[BB3_NONCHR:%.*]], !prof !16 ; CHECK: bb3.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB4]] @@ -288,38 +288,38 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 -; CHECK-NEXT: br i1 [[TMP4]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP3]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB1_NONCHR]] ; CHECK: bb1.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 ; CHECK: bb2.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[I]], align 4 -; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], 12 -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 12 -; CHECK-NEXT: br i1 [[TMP9]], label [[BB4:%.*]], label [[BB3_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[I]], align 4 +; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP6]], 12 +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 12 +; CHECK-NEXT: br i1 [[TMP8]], label [[BB4:%.*]], label [[BB3_SPLIT_NONCHR:%.*]], !prof !15 ; CHECK: bb4: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB7:%.*]] ; CHECK: bb3.split.nonchr: -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP7]], 4 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: br i1 [[TMP11]], label [[BB5_NONCHR:%.*]], label [[BB4_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP6]], 4 +; CHECK-NEXT: [[DOTNOT1:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: br i1 [[DOTNOT1]], label [[BB5_NONCHR:%.*]], label [[BB4_NONCHR:%.*]], !prof !16 ; CHECK: bb4.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB5_NONCHR]] ; CHECK: bb5.nonchr: -; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP7]], 8 -; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 -; CHECK-NEXT: br i1 [[TMP13]], label [[BB7]], label [[BB6_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP6]], 8 +; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 +; CHECK-NEXT: br i1 [[TMP11]], label [[BB7]], label [[BB6_NONCHR:%.*]], !prof !16 ; CHECK: bb6.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB7]] @@ -396,12 +396,12 @@ ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[SUM0]], 42 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP6]], i32 [[SUM0]], i32 [[TMP4]], !prof !16 -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[SUM1_NONCHR]], 43 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM1_NONCHR]], i32 [[TMP9]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP5]], 0 +; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[DOTNOT]], i32 [[SUM0]], i32 [[TMP4]], !prof !16 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM1_NONCHR]], 43 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM1_NONCHR]], i32 [[TMP8]], !prof !16 ; CHECK-NEXT: ret i32 [[SUM2_NONCHR]] ; entry: @@ -455,24 +455,24 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP5]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[SUM0]], 42 -; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM0]], i32 [[TMP9]], !prof !16 -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[SUM1_NONCHR]], 43 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP11]], i32 [[SUM1_NONCHR]], i32 [[TMP12]], !prof !16 -; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP0]], 4 -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 -; CHECK-NEXT: [[TMP15:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP16]], i32 44, i32 88 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM0]], 42 +; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM0]], i32 [[TMP8]], !prof !16 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[SUM1_NONCHR]], 43 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP10]], i32 [[SUM1_NONCHR]], i32 [[TMP11]], !prof !16 +; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP0]], 4 +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 +; CHECK-NEXT: [[TMP14:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i32 [[TMP14]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP15]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP14]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] @@ -555,24 +555,24 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 -; CHECK-NEXT: br i1 [[TMP9]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP8]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[SUM0]], 42 -; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP11]], i32 [[SUM0]], i32 [[TMP12]], !prof !16 -; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 -; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[SUM1_NONCHR]], 43 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP14]], i32 [[SUM1_NONCHR]], i32 [[TMP15]], !prof !16 -; CHECK-NEXT: [[TMP16:%.*]] = and i32 [[SUM0]], 4 -; CHECK-NEXT: [[TMP17:%.*]] = icmp eq i32 [[TMP16]], 0 -; CHECK-NEXT: [[TMP18:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP19]], i32 44, i32 88 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[SUM0]], 42 +; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP10]], i32 [[SUM0]], i32 [[TMP11]], !prof !16 +; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 +; CHECK-NEXT: [[TMP14:%.*]] = add i32 [[SUM1_NONCHR]], 43 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM1_NONCHR]], i32 [[TMP14]], !prof !16 +; CHECK-NEXT: [[TMP15:%.*]] = and i32 [[SUM0]], 4 +; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 +; CHECK-NEXT: [[TMP17:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[TMP17]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP18]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP17]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP16]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP7]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] @@ -656,8 +656,8 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[V1:%.*]] = and i32 [[I0]], 255 -; CHECK-NEXT: [[V2:%.*]] = icmp eq i32 [[V1]], 0 -; CHECK-NEXT: br i1 [[V2]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[V2_NOT:%.*]] = icmp eq i32 [[V1]], 0 +; CHECK-NEXT: br i1 [[V2_NOT]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: [[V3_NONCHR:%.*]] = and i32 [[I0]], 2 ; CHECK-NEXT: [[V4_NONCHR:%.*]] = icmp eq i32 [[V3_NONCHR]], 0 @@ -807,8 +807,8 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[V9:%.*]] = and i32 [[J0]], 4 -; CHECK-NEXT: [[V10:%.*]] = icmp eq i32 [[V9]], 0 -; CHECK-NEXT: br i1 [[V10]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[V10_NOT:%.*]] = icmp eq i32 [[V9]], 0 +; CHECK-NEXT: br i1 [[V10_NOT]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB1_NONCHR]] @@ -948,22 +948,22 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 -; CHECK-NEXT: br i1 [[TMP5]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB1_NONCHR]] ; CHECK: bb1.nonchr: -; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 -; CHECK-NEXT: br i1 [[TMP7]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 +; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 ; CHECK: bb2.nonchr: -; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[J]], align 4 +; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[J]], align 4 ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP3]], [[BB0]] ], [ [[TMP0]], [[BB1_NONCHR]] ], [ [[TMP8]], [[BB2_NONCHR]] ] -; CHECK-NEXT: ret i32 [[TMP9]] +; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[BB0]] ], [ [[TMP0]], [[BB1_NONCHR]] ], [ [[TMP7]], [[BB2_NONCHR]] ] +; CHECK-NEXT: ret i32 [[TMP8]] ; entry: %0 = load i32, i32* %i @@ -1029,25 +1029,25 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 -; CHECK-NEXT: br i1 [[TMP5]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB1_NONCHR]] ; CHECK: bb1.nonchr: -; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[J]], align 4 -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: br i1 [[TMP8]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[J]], align 4 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: br i1 [[TMP7]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 ; CHECK: bb2.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP3]], [[BB0]] ], [ [[TMP6]], [[BB2_NONCHR]] ], [ [[TMP6]], [[BB1_NONCHR]] ] -; CHECK-NEXT: [[TMP10:%.*]] = mul i32 [[TMP9]], 42 -; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP9]], -99 -; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP10]], [[TMP11]] -; CHECK-NEXT: ret i32 [[TMP12]] +; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[BB0]] ], [ [[TMP5]], [[BB2_NONCHR]] ], [ [[TMP5]], [[BB1_NONCHR]] ] +; CHECK-NEXT: [[TMP9:%.*]] = mul i32 [[TMP8]], 42 +; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[TMP8]], -99 +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP9]], [[TMP10]] +; CHECK-NEXT: ret i32 [[TMP11]] ; entry: %0 = load i32, i32* %i @@ -1476,24 +1476,24 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 -; CHECK-NEXT: br i1 [[TMP4]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP3]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB1_NONCHR:%.*]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB1_NONCHR]] ; CHECK: bb1.nonchr: ; CHECK-NEXT: [[V40_NONCHR:%.*]] = add i32 [[TMP0]], 44 -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof !16 ; CHECK: bb2.nonchr: ; CHECK-NEXT: [[V41_NONCHR:%.*]] = add i32 [[TMP0]], 99 ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[V40]], [[BB0]] ], [ [[V40_NONCHR]], [[BB2_NONCHR]] ], [ [[V40_NONCHR]], [[BB1_NONCHR]] ] +; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ [[V40]], [[BB0]] ], [ [[V40_NONCHR]], [[BB2_NONCHR]] ], [ [[V40_NONCHR]], [[BB1_NONCHR]] ] ; CHECK-NEXT: [[V42:%.*]] = phi i32 [ [[V41]], [[BB0]] ], [ [[V41_NONCHR]], [[BB2_NONCHR]] ], [ [[V40_NONCHR]], [[BB1_NONCHR]] ] -; CHECK-NEXT: [[V43:%.*]] = add i32 [[V42]], [[TMP7]] +; CHECK-NEXT: [[V43:%.*]] = add i32 [[V42]], [[TMP6]] ; CHECK-NEXT: ret i32 [[V43]] ; entry: @@ -1661,8 +1661,8 @@ ; CHECK-NEXT: br i1 [[CMP4_NONCHR]], label [[BB2]], label [[BB1_NONCHR:%.*]], !prof !16 ; CHECK: bb1.nonchr: ; CHECK-NEXT: [[A1:%.*]] = and i32 [[LI]], 1 -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A1]], 0 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[CMP1]], i32 [[SUM0]], i32 [[SUM1]], !prof !16 +; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq i32 [[A1]], 0 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[CMP1_NOT]], i32 [[SUM0]], i32 [[SUM1]], !prof !16 ; CHECK-NEXT: [[SUM3_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], 44 ; CHECK-NEXT: br label [[BB2]] ; CHECK: bb2: @@ -1744,18 +1744,18 @@ ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP5]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[SUM0]], 85 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM0]], i32 [[TMP9]], !prof !16 -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP11]], i32 44, i32 88 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM0]], 85 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM0]], i32 [[TMP8]], !prof !16 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP10]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] @@ -1842,8 +1842,8 @@ ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[V8:%.*]] = add i32 [[SUM0]], 43 ; CHECK-NEXT: [[V3:%.*]] = and i32 [[I0]], 2 -; CHECK-NEXT: [[V4:%.*]] = icmp eq i32 [[V3]], 0 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[V4]], i32 [[SUM0]], i32 [[V8]], !prof !16 +; CHECK-NEXT: [[V4_NOT:%.*]] = icmp eq i32 [[V3]], 0 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[V4_NOT]], i32 [[SUM0]], i32 [[V8]], !prof !16 ; CHECK-NEXT: [[V6_NONCHR:%.*]] = and i32 [[I0]], 4 ; CHECK-NEXT: [[V5_NONCHR:%.*]] = icmp eq i32 [[V6_NONCHR]], 0 ; CHECK-NEXT: [[V9_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], 44 @@ -2328,7 +2328,7 @@ ; CHECK-LABEL: @test_chr_23( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[V0:%.*]], 50 -; CHECK-NEXT: [[V10:%.*]] = icmp ne i64 [[TMP0]], -50 +; CHECK-NEXT: [[V10_NOT:%.*]] = icmp eq i64 [[TMP0]], -50 ; CHECK-NEXT: ret i64 99 ; entry: diff --git a/llvm/test/Transforms/SimplifyCFG/merge-cond-stores.ll b/llvm/test/Transforms/SimplifyCFG/merge-cond-stores.ll --- a/llvm/test/Transforms/SimplifyCFG/merge-cond-stores.ll +++ b/llvm/test/Transforms/SimplifyCFG/merge-cond-stores.ll @@ -42,9 +42,9 @@ define void @test_simple_commuted(i32* %p, i32 %a, i32 %b) { ; CHECK-LABEL: @test_simple_commuted( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0 +; CHECK-NEXT: [[X1_NOT:%.*]] = icmp eq i32 [[A:%.*]], 0 ; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0 -; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[X1]], [[X2]] +; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[X1_NOT]], [[X2]] ; CHECK-NEXT: br i1 [[TMP0]], label [[TMP1:%.*]], label [[TMP2:%.*]] ; CHECK: 1: ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32 @@ -274,13 +274,13 @@ ; CHECK-NEXT: [[Z2:%.*]] = select i1 [[X1]], i32 [[B:%.*]], i32 0 ; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B]], 0 ; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[A]], [[B]] -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]] -; CHECK: 2: +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[DOTNOT]], label [[TMP2:%.*]], label [[TMP1:%.*]] +; CHECK: 1: ; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 1 ; CHECK-NEXT: store i32 [[SIMPLIFYCFG_MERGE]], i32* [[P:%.*]], align 4 -; CHECK-NEXT: br label [[TMP3]] -; CHECK: 3: +; CHECK-NEXT: br label [[TMP2]] +; CHECK: 2: ; CHECK-NEXT: [[Z4:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 3 ; CHECK-NEXT: ret i32 [[Z4]] ;