Index: llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp =================================================================== --- llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -2179,6 +2179,19 @@ const T *S = cast(WorkItem->S); int Cost = 0; + + // We may have some zero operands, and we shouldn't really charge for those. + // So how many non-zero coeffients are there? + int NumTerms = llvm::count_if(S->operands(), [](const SCEV *Op) { + return !Op->isZero(); + }); + // Ignoring constant term (operand 0), how many of the coeffients are u> 1? + int NumNonZeroDegreeNonOneTerms = + llvm::count_if(S->operands(), [](const SCEV *Op) { + auto *SConst = dyn_cast(Op); + return !SConst || SConst->getAPInt().ugt(1); + }); + SmallVector Opcodes; auto CastCost = [&](unsigned Opcode) { Opcodes.push_back(Opcode); @@ -2186,9 +2199,10 @@ S->getOperand(0)->getType(), TTI::CastContextHint::None, CostKind); }; - auto ArithCost = [&](unsigned Opcode) { + auto ArithCost = [&](unsigned Opcode, unsigned NumRequired) { Opcodes.push_back(Opcode); - return TTI.getArithmeticInstrCost(Opcode, S->getType(), CostKind); + int Cost = TTI.getArithmeticInstrCost(Opcode, S->getType(), CostKind); + return Cost * NumRequired; }; switch (S->getSCEVType()) { @@ -2208,17 +2222,17 @@ if (auto *SC = dyn_cast(S->getOperand(1))) if (SC->getAPInt().isPowerOf2()) Opcode = Instruction::LShr; - Cost = ArithCost(Opcode); + Cost = ArithCost(Opcode, 1); break; } case scAddExpr: - Cost = ArithCost(Instruction::Add); + Cost = ArithCost(Instruction::Add, NumTerms - 1); break; case scMulExpr: // TODO: this is a very pessimistic cost modelling for Mul, // because of Bin Pow algorithm actually used by the expander, // see SCEVExpander::visitMulExpr(), ExpandOpBinPowN(). - Cost = ArithCost(Instruction::Mul); + Cost = ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms); break; case scSMaxExpr: case scUMaxExpr: @@ -2236,31 +2250,16 @@ break; } case scAddRecExpr: { - int AddCost = ArithCost(Instruction::Add); - int MulCost = ArithCost(Instruction::Mul); - - // In this polynominal, we may have some zero operands, and we shouldn't - // really charge for those. So how many non-zero coeffients are there? - int NumTerms = llvm::count_if(S->operands(), [](const SCEV *Op) { - return !Op->isZero(); - }); assert(NumTerms >= 1 && "Polynominal should have at least one term."); assert(!(*std::prev(S->operands().end()))->isZero() && "Last operand should not be zero"); // Much like with normal add expr, the polynominal will require // one less addition than the number of it's terms. - Cost = AddCost * (NumTerms - 1); - - // Ignoring constant term (operand 0), how many of the coeffients are u> 1? - int NumNonZeroDegreeNonOneTerms = - llvm::count_if(S->operands(), [](const SCEV *Op) { - auto *SConst = dyn_cast(Op); - return !SConst || SConst->getAPInt().ugt(1); - }); + int AddCost = ArithCost(Instruction::Add, NumTerms - 1); // Here, *each* one of those will require a multiplication. - Cost += MulCost * NumNonZeroDegreeNonOneTerms; - + int MulCost = ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms); + Cost = AddCost + MulCost; // What is the degree of this polynominal? int PolyDegree = S->getNumOperands() - 1; assert(PolyDegree >= 1 && "Should be at least affine."); Index: llvm/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll +++ llvm/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll @@ -21,7 +21,7 @@ ; PTR64: loop: ; PTR64-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR64-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] +; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 ; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[END]] ; PTR64-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR64: exit.loopexit: @@ -41,7 +41,7 @@ ; PTR32: loop: ; PTR32-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR32-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] +; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 ; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[END]] ; PTR32-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR32: exit.loopexit: @@ -84,9 +84,9 @@ ; PTR64: loop: ; PTR64-NEXT: [[P_01_US_US:%.*]] = phi i8* [ [[BUF]], [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR64-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] -; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[END]] -; PTR64-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 +; PTR64-NEXT: [[CMP:%.*]] = icmp ult i8* [[GEP]], [[END]] +; PTR64-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR64: exit.loopexit: ; PTR64-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] ; PTR64-NEXT: br label [[EXIT]] @@ -104,9 +104,9 @@ ; PTR32: loop: ; PTR32-NEXT: [[P_01_US_US:%.*]] = phi i8* [ [[BUF]], [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR32-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] -; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[END]] -; PTR32-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 +; PTR32-NEXT: [[CMP:%.*]] = icmp ult i8* [[GEP]], [[END]] +; PTR32-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR32: exit.loopexit: ; PTR32-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] ; PTR32-NEXT: br label [[EXIT]] @@ -146,18 +146,15 @@ ; PTR64-NEXT: [[GUARD:%.*]] = icmp ult i32 0, [[CNT]] ; PTR64-NEXT: br i1 [[GUARD]], label [[PREHEADER:%.*]], label [[EXIT:%.*]] ; PTR64: preheader: -; PTR64-NEXT: [[TMP1:%.*]] = add i32 [[EI]], -1 -; PTR64-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[BI]] -; PTR64-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64 -; PTR64-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[TMP3]], 1 -; PTR64-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to i8* ; PTR64-NEXT: br label [[LOOP:%.*]] ; PTR64: loop: ; PTR64-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] +; PTR64-NEXT: [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[IVNEXT:%.*]], [[LOOP]] ] ; PTR64-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] -; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[TMP5]] -; PTR64-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 +; PTR64-NEXT: [[IVNEXT]] = add nuw i32 [[IV]], 1 +; PTR64-NEXT: [[CMP:%.*]] = icmp ult i32 [[IVNEXT]], [[CNT]] +; PTR64-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR64: exit.loopexit: ; PTR64-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] ; PTR64-NEXT: br label [[EXIT]] @@ -171,17 +168,18 @@ ; PTR32-NEXT: [[BI:%.*]] = ptrtoint i8* [[BUF:%.*]] to i32 ; PTR32-NEXT: [[EI:%.*]] = ptrtoint i8* [[END:%.*]] to i32 ; PTR32-NEXT: [[CNT:%.*]] = sub i32 [[EI]], [[BI]] -; PTR32-NEXT: [[CNT1:%.*]] = inttoptr i32 [[CNT]] to i8* ; PTR32-NEXT: [[GUARD:%.*]] = icmp ult i32 0, [[CNT]] ; PTR32-NEXT: br i1 [[GUARD]], label [[PREHEADER:%.*]], label [[EXIT:%.*]] ; PTR32: preheader: ; PTR32-NEXT: br label [[LOOP:%.*]] ; PTR32: loop: ; PTR32-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] +; PTR32-NEXT: [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[IVNEXT:%.*]], [[LOOP]] ] ; PTR32-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] -; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[CNT1]] -; PTR32-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 +; PTR32-NEXT: [[IVNEXT]] = add nuw i32 [[IV]], 1 +; PTR32-NEXT: [[CMP:%.*]] = icmp ult i32 [[IVNEXT]], [[CNT]] +; PTR32-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR32: exit.loopexit: ; PTR32-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] ; PTR32-NEXT: br label [[EXIT]] @@ -231,10 +229,10 @@ ; PTR64-NEXT: [[P_01_US_US:%.*]] = phi i8* [ [[BUF]], [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR64-NEXT: [[IV:%.*]] = phi i32 [ [[BI]], [[PREHEADER]] ], [ [[IVNEXT:%.*]], [[LOOP]] ] ; PTR64-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] +; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 ; PTR64-NEXT: [[IVNEXT]] = add nuw i32 [[IV]], 1 -; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IVNEXT]], [[CNT]] -; PTR64-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; PTR64-NEXT: [[CMP:%.*]] = icmp ult i32 [[IVNEXT]], [[CNT]] +; PTR64-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR64: exit.loopexit: ; PTR64-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] ; PTR64-NEXT: br label [[EXIT]] @@ -256,10 +254,10 @@ ; PTR32-NEXT: [[P_01_US_US:%.*]] = phi i8* [ [[BUF]], [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR32-NEXT: [[IV:%.*]] = phi i32 [ [[BI]], [[PREHEADER]] ], [ [[IVNEXT:%.*]], [[LOOP]] ] ; PTR32-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 -; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] +; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]], align 1 ; PTR32-NEXT: [[IVNEXT]] = add nuw i32 [[IV]], 1 -; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IVNEXT]], [[CNT]] -; PTR32-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; PTR32-NEXT: [[CMP:%.*]] = icmp ult i32 [[IVNEXT]], [[CNT]] +; PTR32-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR32: exit.loopexit: ; PTR32-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] ; PTR32-NEXT: br label [[EXIT]] Index: llvm/test/Transforms/IndVarSimplify/X86/loop-invariant-conditions.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/X86/loop-invariant-conditions.ll +++ llvm/test/Transforms/IndVarSimplify/X86/loop-invariant-conditions.ll @@ -193,7 +193,7 @@ define void @test7(i64 %start, i64* %inc_ptr) { ; CHECK-LABEL: @test7( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !0 +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, [[RNG0:!range !.*]] ; CHECK-NEXT: [[OK:%.*]] = icmp sge i64 [[INC]], 0 ; CHECK-NEXT: br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]] ; CHECK: loop.preheader: @@ -311,15 +311,12 @@ define void @test3_neg(i64 %start) { ; CHECK-LABEL: @test3_neg( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[START:%.*]], -1 -; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i64 [[START]], i64 -1 -; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[SMAX]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP1]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[FOR_END:%.*]] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END:%.*]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -339,19 +336,16 @@ define void @test4_neg(i64 %start) { ; CHECK-LABEL: @test4_neg( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[START:%.*]], 0 -; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP0]], i64 [[START]], i64 0 -; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[SMAX]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[TMP1]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[LOOP]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -405,7 +399,7 @@ define void @test8(i64 %start, i64* %inc_ptr) { ; CHECK-LABEL: @test8( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !1 +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, [[RNG1:!range !.*]] ; CHECK-NEXT: [[OK:%.*]] = icmp sge i64 [[INC]], 0 ; CHECK-NEXT: br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]] ; CHECK: loop.preheader: @@ -525,7 +519,7 @@ define void @test11(i64* %inc_ptr) { ; CHECK-LABEL: @test11( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !0 +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, [[RNG0]] ; CHECK-NEXT: [[NE_COND:%.*]] = icmp ne i64 [[INC]], 0 ; CHECK-NEXT: br i1 [[NE_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] ; CHECK: loop.preheader: @@ -576,7 +570,7 @@ define void @test12(i64* %inc_ptr) { ; CHECK-LABEL: @test12( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !0 +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], align 8, [[RNG0]] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] Index: llvm/test/Transforms/IndVarSimplify/elim-extend.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/elim-extend.ll +++ llvm/test/Transforms/IndVarSimplify/elim-extend.ll @@ -63,7 +63,7 @@ ; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP_PREHEADER:%.*]], label [[RETURN:%.*]] ; CHECK: loop.preheader: ; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[INIT]] to i64 -; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = sext i32 [[LIMIT]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT]] to i64 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] @@ -74,8 +74,8 @@ ; CHECK-NEXT: store i8 0, i8* [[POSTADR]], align 1 ; CHECK-NEXT: [[POSTADRNSW:%.*]] = getelementptr i8, i8* [[BASE]], i64 [[INDVARS_IV_NEXT]] ; CHECK-NEXT: store i8 0, i8* [[POSTADRNSW]], align 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[TMP1]], [[INDVARS_IV_NEXT]] +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: br label [[RETURN]] ; CHECK: return: @@ -140,8 +140,8 @@ ; CHECK-NEXT: store i8 0, i8* [[ADR2]], align 1 ; CHECK-NEXT: [[ADR3:%.*]] = getelementptr i8, i8* [[ADDRESS]], i64 [[INDVARS_IV_NEXT]] ; CHECK-NEXT: store i8 0, i8* [[ADR3]], align 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP0]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[INNERLOOP]], label [[INNEREXIT:%.*]] +; CHECK-NEXT: [[INNERCMP:%.*]] = icmp sgt i64 [[TMP0]], [[INDVARS_IV_NEXT]] +; CHECK-NEXT: br i1 [[INNERCMP]], label [[INNERLOOP]], label [[INNEREXIT:%.*]] ; CHECK: innerexit: ; CHECK-NEXT: [[INNERCOUNT_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV_NEXT]], [[INNERLOOP]] ] ; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[INNERCOUNT_LCSSA_WIDE]] to i32 @@ -154,8 +154,8 @@ ; CHECK-NEXT: [[ADR5:%.*]] = getelementptr i8, i8* [[ADDRESS]], i64 [[OFS5]] ; CHECK-NEXT: store i8 0, i8* [[ADR5]], align 1 ; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nuw nsw i64 [[INDVARS_IV1]], 1 -; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT2]], [[WIDE_TRIP_COUNT]] -; CHECK-NEXT: br i1 [[EXITCOND4]], label [[OUTERLOOP]], label [[RETURN:%.*]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT2]], [[WIDE_TRIP_COUNT]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[OUTERLOOP]], label [[RETURN:%.*]] ; CHECK: return: ; CHECK-NEXT: ret void ; Index: llvm/test/Transforms/IndVarSimplify/lftr.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr.ll +++ llvm/test/Transforms/IndVarSimplify/lftr.ll @@ -14,7 +14,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: store i32 [[I]], i32* @A +; CHECK-NEXT: store i32 [[I]], i32* @A, align 4 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 1001 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: @@ -42,7 +42,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1000, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = sub nsw i32 [[I]], 1 -; CHECK-NEXT: store i32 [[I]], i32* @A +; CHECK-NEXT: store i32 [[I]], i32* @A, align 4 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[I]], 0 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: @@ -73,7 +73,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 7, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: store i32 [[I]], i32* @A +; CHECK-NEXT: store i32 [[I]], i32* @A, align 4 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 33 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: @@ -103,7 +103,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 7, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: store i32 [[I]], i32* @A +; CHECK-NEXT: store i32 [[I]], i32* @A, align 4 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 33 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: @@ -132,7 +132,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 7, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: store i32 [[I]], i32* @A +; CHECK-NEXT: store i32 [[I]], i32* @A, align 4 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 33 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: @@ -160,12 +160,13 @@ ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 10, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[I]], i32 1) -; CHECK-NEXT: store i32 [[I]], i32* @A +; CHECK-NEXT: store i32 [[I]], i32* @A, align 4 ; CHECK-NEXT: [[I2:%.*]] = mul i32 [[I]], [[I]] -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp sgt i32 [[I2]], 0 -; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] +; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[I2]], 0 +; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: ; CHECK-NEXT: ret i32 0 +; entry: br label %loop @@ -235,7 +236,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[I1:%.*]] = phi i8 [ [[I1_INC:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[I1_INC]] = add nuw nsw i8 [[I1]], 1 -; CHECK-NEXT: store volatile i8 0, i8* [[A:%.*]] +; CHECK-NEXT: store volatile i8 0, i8* [[A:%.*]], align 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 [[I1_INC]], [[TMP2]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: @@ -335,7 +336,7 @@ ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: call void @bar(i32 [[INDVARS_IV]]) #2 +; CHECK-NEXT: call void @bar(i32 [[INDVARS_IV]]) [[ATTR2:#.*]] ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], 512 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] @@ -364,7 +365,7 @@ ; CHECK-NEXT: br label [[DO_BODY:%.*]] ; CHECK: do.body: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[DO_BODY]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: call void @bar(i32 [[INDVARS_IV]]) #2 +; CHECK-NEXT: call void @bar(i32 [[INDVARS_IV]]) [[ATTR2]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[INDVARS_IV]], 255 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1 ; CHECK-NEXT: br i1 [[CMP]], label [[DO_END:%.*]], label [[DO_BODY]] @@ -414,9 +415,9 @@ ; CHECK-NEXT: [[ADD3:%.*]] = fadd float [[TEMP2]], [[MUL]] ; CHECK-NEXT: store float [[ADD3]], float* [[ARRAYIDX2]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 -; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[SUB]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]] +; CHECK-NEXT: [[TEMP3:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TEMP3]], [[SUB]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]] ; CHECK: for.end.loopexit: ; CHECK-NEXT: br label [[FOR_END]] ; CHECK: for.end: Index: llvm/test/Transforms/IndVarSimplify/ult-sub-to-eq.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/ult-sub-to-eq.ll +++ llvm/test/Transforms/IndVarSimplify/ult-sub-to-eq.ll @@ -12,7 +12,7 @@ ; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[DATA_LEN]], [[SAMPLE]] ; CHECK-NEXT: br i1 [[CMP4]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]] ; CHECK: for.body.preheader: -; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SUB]] to i64 +; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SUB]] to i64 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_PREHEADER]] ] @@ -27,8 +27,8 @@ ; CHECK-NEXT: [[ADD3:%.*]] = fadd float [[TMP2]], [[MUL]] ; CHECK-NEXT: store float [[ADD3]], float* [[ARRAYIDX2]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], [[ZEXT]] +; CHECK-NEXT: br i1 [[TMP3]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]] ; CHECK: for.end.loopexit: ; CHECK-NEXT: br label [[FOR_END]] ; CHECK: for.end: Index: llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll +++ llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll @@ -457,15 +457,13 @@ ; CHECK-NEXT: br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]] ; CHECK: for.cond.preheader: ; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[INIT]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[INIT]], [[B:%.*]] -; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[INIT]], i32 [[B]] -; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[B:%.*]] to i64 ; CHECK-NEXT: br label [[FOR_COND:%.*]] ; CHECK: for.cond: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ] ; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ] -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 Index: llvm/test/Transforms/LoopUnroll/runtime-small-upperbound.ll =================================================================== --- llvm/test/Transforms/LoopUnroll/runtime-small-upperbound.ll +++ llvm/test/Transforms/LoopUnroll/runtime-small-upperbound.ll @@ -100,63 +100,15 @@ ; UPPER-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X]], 17 ; UPPER-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] ; UPPER: loop.preheader: -; UPPER-NEXT: [[TMP1:%.*]] = sub i32 16, [[X]] -; UPPER-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], 2 -; UPPER-NEXT: [[TMP3:%.*]] = add nuw nsw i32 [[TMP2]], 1 -; UPPER-NEXT: [[TMP4:%.*]] = urem i32 [[TMP2]], 6 -; UPPER-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], 1 -; UPPER-NEXT: [[XTRAITER:%.*]] = urem i32 [[TMP5]], 6 -; UPPER-NEXT: [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0 -; UPPER-NEXT: br i1 [[LCMP_MOD]], label [[LOOP_PROL_PREHEADER:%.*]], label [[LOOP_PROL_LOOPEXIT:%.*]] -; UPPER: loop.prol.preheader: -; UPPER-NEXT: br label [[LOOP_PROL:%.*]] -; UPPER: loop.prol: -; UPPER-NEXT: [[IV_PROL:%.*]] = phi i32 [ [[IV_NEXT_PROL:%.*]], [[LOOP_PROL]] ], [ [[X]], [[LOOP_PROL_PREHEADER]] ] -; UPPER-NEXT: [[PTR_PROL:%.*]] = phi i8* [ [[PTR_NEXT_PROL:%.*]], [[LOOP_PROL]] ], [ [[Y]], [[LOOP_PROL_PREHEADER]] ] -; UPPER-NEXT: [[PROL_ITER:%.*]] = phi i32 [ [[XTRAITER]], [[LOOP_PROL_PREHEADER]] ], [ [[PROL_ITER_SUB:%.*]], [[LOOP_PROL]] ] -; UPPER-NEXT: [[IV_NEXT_PROL]] = add nuw i32 [[IV_PROL]], 4 -; UPPER-NEXT: [[PTR_NEXT_PROL]] = getelementptr inbounds i8, i8* [[PTR_PROL]], i32 1 -; UPPER-NEXT: store i8 [[ARG:%.*]], i8* [[PTR_NEXT_PROL]], align 1 -; UPPER-NEXT: [[TMP6:%.*]] = icmp ult i32 [[IV_NEXT_PROL]], 17 -; UPPER-NEXT: [[PROL_ITER_SUB]] = sub i32 [[PROL_ITER]], 1 -; UPPER-NEXT: [[PROL_ITER_CMP:%.*]] = icmp ne i32 [[PROL_ITER_SUB]], 0 -; UPPER-NEXT: br i1 [[PROL_ITER_CMP]], label [[LOOP_PROL]], label [[LOOP_PROL_LOOPEXIT_UNR_LCSSA:%.*]], [[LOOP0:!llvm.loop !.*]] -; UPPER: loop.prol.loopexit.unr-lcssa: -; UPPER-NEXT: [[IV_UNR_PH:%.*]] = phi i32 [ [[IV_NEXT_PROL]], [[LOOP_PROL]] ] -; UPPER-NEXT: [[PTR_UNR_PH:%.*]] = phi i8* [ [[PTR_NEXT_PROL]], [[LOOP_PROL]] ] -; UPPER-NEXT: br label [[LOOP_PROL_LOOPEXIT]] -; UPPER: loop.prol.loopexit: -; UPPER-NEXT: [[IV_UNR:%.*]] = phi i32 [ [[X]], [[LOOP_PREHEADER]] ], [ [[IV_UNR_PH]], [[LOOP_PROL_LOOPEXIT_UNR_LCSSA]] ] -; UPPER-NEXT: [[PTR_UNR:%.*]] = phi i8* [ [[Y]], [[LOOP_PREHEADER]] ], [ [[PTR_UNR_PH]], [[LOOP_PROL_LOOPEXIT_UNR_LCSSA]] ] -; UPPER-NEXT: [[TMP7:%.*]] = icmp ult i32 [[TMP2]], 5 -; UPPER-NEXT: br i1 [[TMP7]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_PREHEADER_NEW:%.*]] -; UPPER: loop.preheader.new: ; UPPER-NEXT: br label [[LOOP:%.*]] ; UPPER: loop: -; UPPER-NEXT: [[IV:%.*]] = phi i32 [ [[IV_UNR]], [[LOOP_PREHEADER_NEW]] ], [ [[IV_NEXT_5:%.*]], [[LOOP]] ] -; UPPER-NEXT: [[PTR:%.*]] = phi i8* [ [[PTR_UNR]], [[LOOP_PREHEADER_NEW]] ], [ [[PTR_NEXT_5:%.*]], [[LOOP]] ] -; UPPER-NEXT: [[IV_NEXT:%.*]] = add nuw i32 [[IV]], 4 -; UPPER-NEXT: [[PTR_NEXT:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i32 1 -; UPPER-NEXT: store i8 [[ARG]], i8* [[PTR_NEXT]], align 1 -; UPPER-NEXT: [[IV_NEXT_1:%.*]] = add nuw i32 [[IV_NEXT]], 4 -; UPPER-NEXT: [[PTR_NEXT_1:%.*]] = getelementptr inbounds i8, i8* [[PTR_NEXT]], i32 1 -; UPPER-NEXT: store i8 [[ARG]], i8* [[PTR_NEXT_1]], align 1 -; UPPER-NEXT: [[IV_NEXT_2:%.*]] = add nuw i32 [[IV_NEXT_1]], 4 -; UPPER-NEXT: [[PTR_NEXT_2:%.*]] = getelementptr inbounds i8, i8* [[PTR_NEXT_1]], i32 1 -; UPPER-NEXT: store i8 [[ARG]], i8* [[PTR_NEXT_2]], align 1 -; UPPER-NEXT: [[IV_NEXT_3:%.*]] = add nuw i32 [[IV_NEXT_2]], 4 -; UPPER-NEXT: [[PTR_NEXT_3:%.*]] = getelementptr inbounds i8, i8* [[PTR_NEXT_2]], i32 1 -; UPPER-NEXT: store i8 [[ARG]], i8* [[PTR_NEXT_3]], align 1 -; UPPER-NEXT: [[IV_NEXT_4:%.*]] = add nuw i32 [[IV_NEXT_3]], 4 -; UPPER-NEXT: [[PTR_NEXT_4:%.*]] = getelementptr inbounds i8, i8* [[PTR_NEXT_3]], i32 1 -; UPPER-NEXT: store i8 [[ARG]], i8* [[PTR_NEXT_4]], align 1 -; UPPER-NEXT: [[IV_NEXT_5]] = add nuw i32 [[IV_NEXT_4]], 4 -; UPPER-NEXT: [[PTR_NEXT_5]] = getelementptr inbounds i8, i8* [[PTR_NEXT_4]], i32 1 -; UPPER-NEXT: store i8 [[ARG]], i8* [[PTR_NEXT_5]], align 1 -; UPPER-NEXT: [[TMP8:%.*]] = icmp ult i32 [[IV_NEXT_5]], 17 -; UPPER-NEXT: br i1 [[TMP8]], label [[LOOP]], label [[EXIT_LOOPEXIT_UNR_LCSSA:%.*]] -; UPPER: exit.loopexit.unr-lcssa: -; UPPER-NEXT: br label [[EXIT_LOOPEXIT]] +; UPPER-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ [[X]], [[LOOP_PREHEADER]] ] +; UPPER-NEXT: [[PTR:%.*]] = phi i8* [ [[PTR_NEXT:%.*]], [[LOOP]] ], [ [[Y]], [[LOOP_PREHEADER]] ] +; UPPER-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 4 +; UPPER-NEXT: [[PTR_NEXT]] = getelementptr inbounds i8, i8* [[PTR]], i32 1 +; UPPER-NEXT: store i8 [[ARG:%.*]], i8* [[PTR_NEXT]], align 1 +; UPPER-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IV_NEXT]], 17 +; UPPER-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; UPPER: exit.loopexit: ; UPPER-NEXT: br label [[EXIT]] ; UPPER: exit: