diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -512,6 +512,7 @@ const SCEV *getConstant(ConstantInt *V); const SCEV *getConstant(const APInt &Val); const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false); + const SCEV *getPtrToIntExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h b/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h --- a/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h @@ -33,6 +33,7 @@ // Except in the trivial case described above, we do not know how to divide // Expr by Denominator for the following functions with empty implementation. + void visitPtrToIntExpr(const SCEVPtrToIntExpr *Numerator) {} void visitTruncateExpr(const SCEVTruncateExpr *Numerator) {} void visitZeroExtendExpr(const SCEVZeroExtendExpr *Numerator) {} void visitSignExtendExpr(const SCEVSignExtendExpr *Numerator) {} diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h --- a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -40,7 +40,7 @@ // folders simpler. scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr, scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUMinExpr, scSMinExpr, - scUnknown, scCouldNotCompute + scPtrToInt, scUnknown, scCouldNotCompute }; /// This class represents a constant integer value. @@ -72,13 +72,13 @@ } /// This is the base class for unary cast operator classes. - class SCEVIntegralCastExpr : public SCEV { + class SCEVCastExpr : public SCEV { protected: std::array Operands; Type *Ty; - SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, - const SCEV *op, Type *ty); + SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, const SCEV *op, + Type *ty); public: const SCEV *getOperand() const { return Operands[0]; } @@ -95,6 +95,35 @@ size_t getNumOperands() const { return 1; } Type *getType() const { return Ty; } + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const SCEV *S) { + return S->getSCEVType() == scPtrToInt || S->getSCEVType() == scTruncate || + S->getSCEVType() == scZeroExtend || + S->getSCEVType() == scSignExtend; + } + }; + + /// This class represents a cast from a pointer to a pointer-sized integer + /// value. + class SCEVPtrToIntExpr : public SCEVCastExpr { + friend class ScalarEvolution; + + SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op, Type *ITy); + + public: + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const SCEV *S) { + return S->getSCEVType() == scPtrToInt; + } + }; + + /// This is the base class for unary integral cast operator classes. + class SCEVIntegralCastExpr : public SCEVCastExpr { + protected: + SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, + const SCEV *op, Type *ty); + + public: /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const SCEV *S) { return S->getSCEVType() == scTruncate || @@ -541,6 +570,8 @@ switch (S->getSCEVType()) { case scConstant: return ((SC*)this)->visitConstant((const SCEVConstant*)S); + case scPtrToInt: + return ((SC *)this)->visitPtrToIntExpr((const SCEVPtrToIntExpr *)S); case scTruncate: return ((SC*)this)->visitTruncateExpr((const SCEVTruncateExpr*)S); case scZeroExtend: @@ -606,10 +637,11 @@ case scConstant: case scUnknown: continue; + case scPtrToInt: case scTruncate: case scZeroExtend: case scSignExtend: - push(cast(S)->getOperand()); + push(cast(S)->getOperand()); continue; case scAddExpr: case scMulExpr: @@ -698,6 +730,13 @@ return Constant; } + const SCEV *visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) { + const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand()); + return Operand == Expr->getOperand() + ? Expr + : SE.getPtrToIntExpr(Operand, Expr->getType()); + } + const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) { const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand()); return Operand == Expr->getOperand() diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h --- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h +++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h @@ -446,6 +446,8 @@ Value *visitConstant(const SCEVConstant *S) { return S->getValue(); } + Value *visitPtrToIntExpr(const SCEVPtrToIntExpr *S); + Value *visitTruncateExpr(const SCEVTruncateExpr *S); Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -252,6 +252,13 @@ case scConstant: cast(this)->getValue()->printAsOperand(OS, false); return; + case scPtrToInt: { + const SCEVPtrToIntExpr *PtrToInt = cast(this); + const SCEV *Op = PtrToInt->getOperand(); + OS << "(ptrtoint " << *Op->getType() << " " << *Op << " to " + << *PtrToInt->getType() << ")"; + return; + } case scTruncate: { const SCEVTruncateExpr *Trunc = cast(this); const SCEV *Op = Trunc->getOperand(); @@ -375,10 +382,11 @@ switch (getSCEVType()) { case scConstant: return cast(this)->getType(); + case scPtrToInt: case scTruncate: case scZeroExtend: case scSignExtend: - return cast(this)->getType(); + return cast(this)->getType(); case scAddRecExpr: case scMulExpr: case scUMaxExpr: @@ -456,13 +464,24 @@ return getConstant(ConstantInt::get(ITy, V, isSigned)); } -SCEVIntegralCastExpr::SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID, - SCEVTypes SCEVTy, const SCEV *op, - Type *ty) +SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, + const SCEV *op, Type *ty) : SCEV(ID, SCEVTy, computeExpressionSize(op)), Ty(ty) { Operands[0] = op; } +SCEVPtrToIntExpr::SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op, + Type *ITy) + : SCEVCastExpr(ID, scPtrToInt, Op, ITy) { + assert(getOperand()->getType()->isPointerTy() && Ty->isIntegerTy() && + "Must be a non-bit-width-changing pointer-to-integer cast!"); +} + +SCEVIntegralCastExpr::SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID, + SCEVTypes SCEVTy, const SCEV *op, + Type *ty) + : SCEVCastExpr(ID, SCEVTy, op, ty) {} + SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID, const SCEV *op, Type *ty) : SCEVIntegralCastExpr(ID, scTruncate, op, ty) { @@ -790,11 +809,12 @@ return X; } + case scPtrToInt: case scTruncate: case scZeroExtend: case scSignExtend: { - const SCEVIntegralCastExpr *LC = cast(LHS); - const SCEVIntegralCastExpr *RC = cast(RHS); + const SCEVCastExpr *LC = cast(LHS); + const SCEVCastExpr *RC = cast(RHS); // Compare cast expressions by operand. int X = CompareSCEVComplexity(EqCacheSCEV, EqCacheValue, LI, @@ -1013,6 +1033,42 @@ // SCEV Expression folder implementations //===----------------------------------------------------------------------===// +const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty, + unsigned Depth) { + assert(Ty->isIntegerTy() && "Target type must be an integer type!"); + + // We could be called with an integer-typed operands during SCEV rewrites. + // Since the operand is an integer already, just perform zext/trunc/self cast. + if (!Op->getType()->isPointerTy()) + return getTruncateOrZeroExtend(Op, Ty); + + FoldingSetNodeID ID; + ID.AddInteger(scPtrToInt); + ID.AddPointer(Op); + void *IP = nullptr; + if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) + return getTruncateOrZeroExtend(S, Ty); + + assert(!isa(Op) && + "SCEVConstant is an integer, no constant folding to do."); + + // FIXME: simplifications. + + // The cast wasn't folded; create an explicit cast node. We can reuse + // the existing insert position since if we get here, we won't have + // made any changes which would invalidate it. + Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType()); + assert(getDataLayout().getTypeSizeInBits(getEffectiveSCEVType( + Op->getType())) == getDataLayout().getTypeSizeInBits(IntPtrTy) && + "We can only model ptrtoint if SCEV's effective (integer) type is " + "sufficiently wide to represent all possible pointer values."); + SCEV *S = new (SCEVAllocator) + SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy); + UniqueSCEVs.InsertNode(S, IP); + addToLoopUseLists(S); + return getTruncateOrZeroExtend(S, Ty); +} + const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth) { assert(getTypeSizeInBits(Op->getType()) > getTypeSizeInBits(Ty) && @@ -3528,15 +3584,18 @@ } const SCEV *ScalarEvolution::getSizeOfExpr(Type *IntTy, Type *AllocTy) { - // We can bypass creating a target-independent - // constant expression and then folding it back into a ConstantInt. - // This is just a compile-time optimization. if (isa(AllocTy)) { Constant *NullPtr = Constant::getNullValue(AllocTy->getPointerTo()); Constant *One = ConstantInt::get(IntTy, 1); Constant *GEP = ConstantExpr::getGetElementPtr(AllocTy, NullPtr, One); - return getSCEV(ConstantExpr::getPtrToInt(GEP, IntTy)); + // Note that the expression we created is the final expression, we don't + // want to simplify it any further Also, if we call a normal getSCEV(), + // we'll end up in an endless recursion. So just create an SCEVUnknown. + return getUnknown(ConstantExpr::getPtrToInt(GEP, IntTy)); } + // We can bypass creating a target-independent + // constant expression and then folding it back into a ConstantInt. + // This is just a compile-time optimization. return getConstant(IntTy, getDataLayout().getTypeAllocSize(AllocTy)); } @@ -5007,8 +5066,15 @@ bool follow(const SCEV *S) { switch (S->getSCEVType()) { - case scConstant: case scTruncate: case scZeroExtend: case scSignExtend: - case scAddExpr: case scMulExpr: case scUMaxExpr: case scSMaxExpr: + case scConstant: + case scPtrToInt: + case scTruncate: + case scZeroExtend: + case scSignExtend: + case scAddExpr: + case scMulExpr: + case scUMaxExpr: + case scSMaxExpr: case scUMinExpr: case scSMinExpr: // These expressions are available if their operand(s) is/are. @@ -5266,6 +5332,9 @@ if (const SCEVConstant *C = dyn_cast(S)) return C->getAPInt().countTrailingZeros(); + if (const SCEVPtrToIntExpr *I = dyn_cast(S)) + return GetMinTrailingZeros(I->getOperand()); + if (const SCEVTruncateExpr *T = dyn_cast(S)) return std::min(GetMinTrailingZeros(T->getOperand()), (uint32_t)getTypeSizeInBits(T->getType())); @@ -5471,6 +5540,11 @@ RangeType)); } + if (const SCEVPtrToIntExpr *PtrToInt = dyn_cast(S)) { + ConstantRange X = getRangeRef(PtrToInt->getOperand(), SignHint); + return setRange(PtrToInt, SignHint, X); + } + if (const SCEVTruncateExpr *Trunc = dyn_cast(S)) { ConstantRange X = getRangeRef(Trunc->getOperand(), SignHint); return setRange(Trunc, SignHint, @@ -6077,6 +6151,7 @@ } else if (ConstantInt *CI = dyn_cast(V)) return getConstant(CI); else if (isa(V)) + // FIXME: we shouldn't special-case null pointer constant. return getZero(V->getType()); else if (GlobalAlias *GA = dyn_cast(V)) return GA->isInterposable() ? getUnknown(V) : getSCEV(GA->getAliasee()); @@ -6412,6 +6487,29 @@ return getSCEV(U->getOperand(0)); break; + case Instruction::PtrToInt: { + // Pointer to integer cast is straight-forward, so do model it. + Value *Ptr = U->getOperand(0); + const SCEV *Op = getSCEV(Ptr); + Type *DstIntTy = U->getType(); + // SCEV doesn't have constant pointer expression type, but it supports + // nullptr constant (and only that one), which is modelled in SCEV as a + // zero integer constant. So just skip the ptrtoint cast for constants. + if (isa(Op)) + return getTruncateOrZeroExtend(Op, DstIntTy); + Type *PtrTy = Ptr->getType(); + Type *IntPtrTy = getDataLayout().getIntPtrType(PtrTy); + // But only if effective SCEV (integer) type is wide enough to represent + // all possible pointer values. + if (getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(PtrTy)) != + getDataLayout().getTypeSizeInBits(IntPtrTy)) + return getUnknown(V); + return getPtrToIntExpr(Op, DstIntTy); + } + case Instruction::IntToPtr: + // Just don't deal with inttoptr casts. + return getUnknown(V); + case Instruction::SDiv: // If both operands are non-negative, this is just an udiv. if (isKnownNonNegative(getSCEV(U->getOperand(0))) && @@ -6426,11 +6524,6 @@ return getURemExpr(getSCEV(U->getOperand(0)), getSCEV(U->getOperand(1))); break; - // It's tempting to handle inttoptr and ptrtoint as no-ops, however this can - // lead to pointer expressions which cannot safely be expanded to GEPs, - // because ScalarEvolution doesn't respect the GEP aliasing rules when - // simplifying integer expressions. - case Instruction::GetElementPtr: return createNodeForGEP(cast(U)); @@ -8090,6 +8183,13 @@ return ConstantExpr::getZExt(CastOp, SZ->getType()); return nullptr; } + case scPtrToInt: { + const SCEVPtrToIntExpr *P2I = cast(V); + if (Constant *CastOp = BuildConstantFromSCEV(P2I->getOperand())) + return ConstantExpr::getPtrToInt(CastOp, P2I->getType()); + + return nullptr; + } case scTruncate: { const SCEVTruncateExpr *ST = cast(V); if (Constant *CastOp = BuildConstantFromSCEV(ST->getOperand())) @@ -8397,6 +8497,13 @@ return getTruncateExpr(Op, Cast->getType()); } + if (const SCEVPtrToIntExpr *Cast = dyn_cast(V)) { + const SCEV *Op = getSCEVAtScope(Cast->getOperand(), L); + if (Op == Cast->getOperand()) + return Cast; // must be loop invariant + return getPtrToIntExpr(Op, Cast->getType()); + } + llvm_unreachable("Unknown SCEV type!"); } @@ -11973,10 +12080,11 @@ switch (S->getSCEVType()) { case scConstant: return LoopInvariant; + case scPtrToInt: case scTruncate: case scZeroExtend: case scSignExtend: - return getLoopDisposition(cast(S)->getOperand(), L); + return getLoopDisposition(cast(S)->getOperand(), L); case scAddRecExpr: { const SCEVAddRecExpr *AR = cast(S); @@ -12080,10 +12188,11 @@ switch (S->getSCEVType()) { case scConstant: return ProperlyDominatesBlock; + case scPtrToInt: case scTruncate: case scZeroExtend: case scSignExtend: - return getBlockDisposition(cast(S)->getOperand(), BB); + return getBlockDisposition(cast(S)->getOperand(), BB); case scAddRecExpr: { // This uses a "dominates" query instead of "properly dominates" query // to test for proper dominance too, because the instruction which diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -663,7 +663,7 @@ L = PickMostRelevantLoop(L, getRelevantLoop(Op), SE.DT); return RelevantLoops[N] = L; } - if (const SCEVIntegralCastExpr *C = dyn_cast(S)) { + if (const SCEVCastExpr *C = dyn_cast(S)) { const Loop *Result = getRelevantLoop(C->getOperand()); return RelevantLoops[C] = Result; } @@ -1661,6 +1661,12 @@ return expand(T); } +Value *SCEVExpander::visitPtrToIntExpr(const SCEVPtrToIntExpr *S) { + Value *V = + expandCodeForImpl(S->getOperand(), S->getOperand()->getType(), false); + return Builder.CreatePtrToInt(V, S->getType()); +} + Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) { Type *Ty = SE.getEffectiveSCEVType(S->getType()); Value *V = expandCodeForImpl( @@ -2241,6 +2247,9 @@ case scUnknown: case scConstant: return 0; + case scPtrToInt: + Cost = CastCost(Instruction::PtrToInt); + break; case scTruncate: Cost = CastCost(Instruction::Trunc); break; @@ -2368,10 +2377,11 @@ return BudgetRemaining < 0; } case scTruncate: + case scPtrToInt: case scZeroExtend: case scSignExtend: { - int Cost = costAndCollectOperands(WorkItem, TTI, - CostKind, Worklist); + int Cost = + costAndCollectOperands(WorkItem, TTI, CostKind, Worklist); BudgetRemaining -= Cost; return false; // Will answer upon next entry into this function. } diff --git a/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll b/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll --- a/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll +++ b/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll @@ -33,9 +33,9 @@ ; CHECK-NEXT: %1 = load i32*, i32** @c, align 8 ; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %sub.ptr.lhs.cast = ptrtoint i32* %1 to i64 -; CHECK-NEXT: --> %sub.ptr.lhs.cast U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: --> (ptrtoint i32* %1 to i64) U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, ptrtoint ([1 x i32]* @b to i64) -; CHECK-NEXT: --> ((-1 * ptrtoint ([1 x i32]* @b to i64)) + %sub.ptr.lhs.cast) U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: --> ((-1 * (ptrtoint [1 x i32]* @b to i64)) + (ptrtoint i32* %1 to i64)) U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %sub.ptr.div = sdiv exact i64 %sub.ptr.sub, 4 ; CHECK-NEXT: --> %sub.ptr.div U: full-set S: [-2305843009213693952,2305843009213693952) Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %arrayidx1 = getelementptr inbounds [1 x i8], [1 x i8]* %arrayidx, i64 0, i64 %sub.ptr.div diff --git a/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll b/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll --- a/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll +++ b/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll @@ -186,19 +186,19 @@ ; CHECK-NEXT: %ptr = bitcast [16 x i8]* @z_addr to i8* ; CHECK-NEXT: --> @z_addr U: [0,-3) S: [-9223372036854775808,9223372036854775805) ; CHECK-NEXT: %int0 = ptrtoint i8* %ptr to i32 -; CHECK-NEXT: --> %int0 U: [0,-3) S: [-2147483648,2147483645) +; CHECK-NEXT: --> (trunc i64 (ptrtoint [16 x i8]* @z_addr to i64) to i32) U: [0,-3) S: [-2147483648,2147483645) ; CHECK-NEXT: %int5 = add i32 %int0, 5 -; CHECK-NEXT: --> (5 + %int0) U: [5,2) S: [-2147483643,-2147483646) +; CHECK-NEXT: --> (5 + (trunc i64 (ptrtoint [16 x i8]* @z_addr to i64) to i32)) U: [5,2) S: [-2147483643,-2147483646) ; CHECK-NEXT: %int.zext = zext i32 %int5 to i64 -; CHECK-NEXT: --> (1 + (zext i32 (4 + %int0) to i64)) U: [1,4294967294) S: [1,4294967297) +; CHECK-NEXT: --> (1 + (zext i32 (4 + (trunc i64 (ptrtoint [16 x i8]* @z_addr to i64) to i32)) to i64)) U: [1,4294967294) S: [1,4294967297) ; CHECK-NEXT: %ptr_noalign = bitcast [16 x i8]* @z_addr_noalign to i8* ; CHECK-NEXT: --> @z_addr_noalign U: full-set S: full-set ; CHECK-NEXT: %int0_na = ptrtoint i8* %ptr_noalign to i32 -; CHECK-NEXT: --> %int0_na U: full-set S: full-set +; CHECK-NEXT: --> (trunc i64 (ptrtoint [16 x i8]* @z_addr_noalign to i64) to i32) U: full-set S: full-set ; CHECK-NEXT: %int5_na = add i32 %int0_na, 5 -; CHECK-NEXT: --> (5 + %int0_na) U: full-set S: full-set +; CHECK-NEXT: --> (5 + (trunc i64 (ptrtoint [16 x i8]* @z_addr_noalign to i64) to i32)) U: full-set S: full-set ; CHECK-NEXT: %int.zext_na = zext i32 %int5_na to i64 -; CHECK-NEXT: --> (zext i32 (5 + %int0_na) to i64) U: [0,4294967296) S: [0,4294967296) +; CHECK-NEXT: --> (zext i32 (5 + (trunc i64 (ptrtoint [16 x i8]* @z_addr_noalign to i64) to i32)) to i64) U: [0,4294967296) S: [0,4294967296) ; CHECK-NEXT: %tmp = load i32, i32* %tmp_addr, align 4 ; CHECK-NEXT: --> %tmp U: full-set S: full-set ; CHECK-NEXT: %mul = and i32 %tmp, -4 diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll --- a/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll +++ b/llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll @@ -18,9 +18,9 @@ ; PTR64_IDX64-NEXT: %tmp = phi i32 [ 0, %bb ], [ %tmp18, %bb17 ] ; PTR64_IDX64-NEXT: --> {0,+,2}<%bb11> U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %bb11: Computable } ; PTR64_IDX64-NEXT: %tmp12 = getelementptr i8, i8* %arg, i64 ptrtoint ([0 x i8]* @global to i64) -; PTR64_IDX64-NEXT: --> (ptrtoint ([0 x i8]* @global to i64) + %arg) U: full-set S: full-set Exits: (ptrtoint ([0 x i8]* @global to i64) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR64_IDX64-NEXT: --> ((ptrtoint [0 x i8]* @global to i64) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i64) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR64_IDX64-NEXT: %tmp13 = bitcast i8* %tmp12 to i32* -; PTR64_IDX64-NEXT: --> (ptrtoint ([0 x i8]* @global to i64) + %arg) U: full-set S: full-set Exits: (ptrtoint ([0 x i8]* @global to i64) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR64_IDX64-NEXT: --> ((ptrtoint [0 x i8]* @global to i64) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i64) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR64_IDX64-NEXT: %tmp14 = load i32, i32* %tmp13, align 4 ; PTR64_IDX64-NEXT: --> %tmp14 U: full-set S: full-set Exits: <> LoopDispositions: { %bb11: Variant } ; PTR64_IDX64-NEXT: %tmp18 = add i32 %tmp, 2 @@ -52,9 +52,9 @@ ; PTR16_IDX16-NEXT: %tmp = phi i32 [ 0, %bb ], [ %tmp18, %bb17 ] ; PTR16_IDX16-NEXT: --> {0,+,2}<%bb11> U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %bb11: Computable } ; PTR16_IDX16-NEXT: %tmp12 = getelementptr i8, i8* %arg, i64 ptrtoint ([0 x i8]* @global to i64) -; PTR16_IDX16-NEXT: --> ((trunc i64 ptrtoint ([0 x i8]* @global to i64) to i16) + %arg) U: full-set S: full-set Exits: ((trunc i64 ptrtoint ([0 x i8]* @global to i64) to i16) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR16_IDX16-NEXT: --> ((ptrtoint [0 x i8]* @global to i16) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i16) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR16_IDX16-NEXT: %tmp13 = bitcast i8* %tmp12 to i32* -; PTR16_IDX16-NEXT: --> ((trunc i64 ptrtoint ([0 x i8]* @global to i64) to i16) + %arg) U: full-set S: full-set Exits: ((trunc i64 ptrtoint ([0 x i8]* @global to i64) to i16) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR16_IDX16-NEXT: --> ((ptrtoint [0 x i8]* @global to i16) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i16) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR16_IDX16-NEXT: %tmp14 = load i32, i32* %tmp13, align 4 ; PTR16_IDX16-NEXT: --> %tmp14 U: full-set S: full-set Exits: <> LoopDispositions: { %bb11: Variant } ; PTR16_IDX16-NEXT: %tmp18 = add i32 %tmp, 2 @@ -105,9 +105,9 @@ ; PTR64_IDX64-NEXT: %tmp = phi i32 [ 0, %bb ], [ %tmp18, %bb17 ] ; PTR64_IDX64-NEXT: --> {0,+,2}<%bb11> U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %bb11: Computable } ; PTR64_IDX64-NEXT: %tmp12 = getelementptr i8, i8* %arg, i32 ptrtoint ([0 x i8]* @global to i32) -; PTR64_IDX64-NEXT: --> ((sext i32 ptrtoint ([0 x i8]* @global to i32) to i64) + %arg) U: full-set S: full-set Exits: ((sext i32 ptrtoint ([0 x i8]* @global to i32) to i64) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR64_IDX64-NEXT: --> ((sext i32 (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i32) to i64) + %arg) U: full-set S: full-set Exits: ((sext i32 (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i32) to i64) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR64_IDX64-NEXT: %tmp13 = bitcast i8* %tmp12 to i32* -; PTR64_IDX64-NEXT: --> ((sext i32 ptrtoint ([0 x i8]* @global to i32) to i64) + %arg) U: full-set S: full-set Exits: ((sext i32 ptrtoint ([0 x i8]* @global to i32) to i64) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR64_IDX64-NEXT: --> ((sext i32 (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i32) to i64) + %arg) U: full-set S: full-set Exits: ((sext i32 (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i32) to i64) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR64_IDX64-NEXT: %tmp14 = load i32, i32* %tmp13, align 4 ; PTR64_IDX64-NEXT: --> %tmp14 U: full-set S: full-set Exits: <> LoopDispositions: { %bb11: Variant } ; PTR64_IDX64-NEXT: %tmp18 = add i32 %tmp, 2 @@ -139,9 +139,9 @@ ; PTR16_IDX16-NEXT: %tmp = phi i32 [ 0, %bb ], [ %tmp18, %bb17 ] ; PTR16_IDX16-NEXT: --> {0,+,2}<%bb11> U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %bb11: Computable } ; PTR16_IDX16-NEXT: %tmp12 = getelementptr i8, i8* %arg, i32 ptrtoint ([0 x i8]* @global to i32) -; PTR16_IDX16-NEXT: --> ((trunc i32 ptrtoint ([0 x i8]* @global to i32) to i16) + %arg) U: full-set S: full-set Exits: ((trunc i32 ptrtoint ([0 x i8]* @global to i32) to i16) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR16_IDX16-NEXT: --> ((ptrtoint [0 x i8]* @global to i16) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i16) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR16_IDX16-NEXT: %tmp13 = bitcast i8* %tmp12 to i32* -; PTR16_IDX16-NEXT: --> ((trunc i32 ptrtoint ([0 x i8]* @global to i32) to i16) + %arg) U: full-set S: full-set Exits: ((trunc i32 ptrtoint ([0 x i8]* @global to i32) to i16) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR16_IDX16-NEXT: --> ((ptrtoint [0 x i8]* @global to i16) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i16) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR16_IDX16-NEXT: %tmp14 = load i32, i32* %tmp13, align 4 ; PTR16_IDX16-NEXT: --> %tmp14 U: full-set S: full-set Exits: <> LoopDispositions: { %bb11: Variant } ; PTR16_IDX16-NEXT: %tmp18 = add i32 %tmp, 2 @@ -192,9 +192,9 @@ ; PTR64_IDX64-NEXT: %tmp = phi i32 [ 0, %bb ], [ %tmp18, %bb17 ] ; PTR64_IDX64-NEXT: --> {0,+,2}<%bb11> U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %bb11: Computable } ; PTR64_IDX64-NEXT: %tmp12 = getelementptr i8, i8* %arg, i128 ptrtoint ([0 x i8]* @global to i128) -; PTR64_IDX64-NEXT: --> ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i64) + %arg) U: full-set S: full-set Exits: ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i64) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR64_IDX64-NEXT: --> ((ptrtoint [0 x i8]* @global to i64) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i64) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR64_IDX64-NEXT: %tmp13 = bitcast i8* %tmp12 to i32* -; PTR64_IDX64-NEXT: --> ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i64) + %arg) U: full-set S: full-set Exits: ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i64) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR64_IDX64-NEXT: --> ((ptrtoint [0 x i8]* @global to i64) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i64) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR64_IDX64-NEXT: %tmp14 = load i32, i32* %tmp13, align 4 ; PTR64_IDX64-NEXT: --> %tmp14 U: full-set S: full-set Exits: <> LoopDispositions: { %bb11: Variant } ; PTR64_IDX64-NEXT: %tmp18 = add i32 %tmp, 2 @@ -226,9 +226,9 @@ ; PTR16_IDX16-NEXT: %tmp = phi i32 [ 0, %bb ], [ %tmp18, %bb17 ] ; PTR16_IDX16-NEXT: --> {0,+,2}<%bb11> U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %bb11: Computable } ; PTR16_IDX16-NEXT: %tmp12 = getelementptr i8, i8* %arg, i128 ptrtoint ([0 x i8]* @global to i128) -; PTR16_IDX16-NEXT: --> ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i16) + %arg) U: full-set S: full-set Exits: ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i16) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR16_IDX16-NEXT: --> ((ptrtoint [0 x i8]* @global to i16) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i16) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR16_IDX16-NEXT: %tmp13 = bitcast i8* %tmp12 to i32* -; PTR16_IDX16-NEXT: --> ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i16) + %arg) U: full-set S: full-set Exits: ((trunc i128 ptrtoint ([0 x i8]* @global to i128) to i16) + %arg) LoopDispositions: { %bb11: Invariant } +; PTR16_IDX16-NEXT: --> ((ptrtoint [0 x i8]* @global to i16) + %arg) U: full-set S: full-set Exits: ((ptrtoint [0 x i8]* @global to i16) + %arg) LoopDispositions: { %bb11: Invariant } ; PTR16_IDX16-NEXT: %tmp14 = load i32, i32* %tmp13, align 4 ; PTR16_IDX16-NEXT: --> %tmp14 U: full-set S: full-set Exits: <> LoopDispositions: { %bb11: Variant } ; PTR16_IDX16-NEXT: %tmp18 = add i32 %tmp, 2 @@ -275,27 +275,49 @@ } define void @zext_ptr_to_i32(i32 %arg, i32 %arg6) { -; X64-LABEL: 'zext_ptr_to_i32' -; X64-NEXT: Classifying expressions for: @zext_ptr_to_i32 -; X64-NEXT: %tmp = sub i32 %arg, ptrtoint ([0 x i8]* @global to i32) -; X64-NEXT: --> ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) LoopDispositions: { %bb7: Invariant } -; X64-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 -; X64-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } -; X64-NEXT: Determining loop execution counts for: @zext_ptr_to_i32 -; X64-NEXT: Loop %bb7: Unpredictable backedge-taken count. -; X64-NEXT: Loop %bb7: Unpredictable max backedge-taken count. -; X64-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; PTR64_IDX64-LABEL: 'zext_ptr_to_i32' +; PTR64_IDX64-NEXT: Classifying expressions for: @zext_ptr_to_i32 +; PTR64_IDX64-NEXT: %tmp = sub i32 %arg, ptrtoint ([0 x i8]* @global to i32) +; PTR64_IDX64-NEXT: --> ((-1 * (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR64_IDX64-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR64_IDX64-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR64_IDX64-NEXT: Determining loop execution counts for: @zext_ptr_to_i32 +; PTR64_IDX64-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR64_IDX64-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR64_IDX64-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. ; -; X32-LABEL: 'zext_ptr_to_i32' -; X32-NEXT: Classifying expressions for: @zext_ptr_to_i32 -; X32-NEXT: %tmp = sub i32 %arg, ptrtoint ([0 x i8]* @global to i32) -; X32-NEXT: --> ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) LoopDispositions: { %bb7: Invariant } -; X32-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 -; X32-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } -; X32-NEXT: Determining loop execution counts for: @zext_ptr_to_i32 -; X32-NEXT: Loop %bb7: Unpredictable backedge-taken count. -; X32-NEXT: Loop %bb7: Unpredictable max backedge-taken count. -; X32-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; PTR64_IDX32-LABEL: 'zext_ptr_to_i32' +; PTR64_IDX32-NEXT: Classifying expressions for: @zext_ptr_to_i32 +; PTR64_IDX32-NEXT: %tmp = sub i32 %arg, ptrtoint ([0 x i8]* @global to i32) +; PTR64_IDX32-NEXT: --> ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR64_IDX32-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR64_IDX32-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR64_IDX32-NEXT: Determining loop execution counts for: @zext_ptr_to_i32 +; PTR64_IDX32-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR64_IDX32-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR64_IDX32-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; +; PTR16_IDX16-LABEL: 'zext_ptr_to_i32' +; PTR16_IDX16-NEXT: Classifying expressions for: @zext_ptr_to_i32 +; PTR16_IDX16-NEXT: %tmp = sub i32 %arg, ptrtoint ([0 x i8]* @global to i32) +; PTR16_IDX16-NEXT: --> ((-1 * (zext i16 (ptrtoint [0 x i8]* @global to i16) to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * (zext i16 (ptrtoint [0 x i8]* @global to i16) to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR16_IDX16-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR16_IDX16-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR16_IDX16-NEXT: Determining loop execution counts for: @zext_ptr_to_i32 +; PTR16_IDX16-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR16_IDX16-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR16_IDX16-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; +; PTR16_IDX32-LABEL: 'zext_ptr_to_i32' +; PTR16_IDX32-NEXT: Classifying expressions for: @zext_ptr_to_i32 +; PTR16_IDX32-NEXT: %tmp = sub i32 %arg, ptrtoint ([0 x i8]* @global to i32) +; PTR16_IDX32-NEXT: --> ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * ptrtoint ([0 x i8]* @global to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR16_IDX32-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR16_IDX32-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR16_IDX32-NEXT: Determining loop execution counts for: @zext_ptr_to_i32 +; PTR16_IDX32-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR16_IDX32-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR16_IDX32-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. ; bb: br label %bb7 @@ -312,16 +334,49 @@ } define void @sext_to_i32(i32 %arg, i32 %arg6) { -; ALL-LABEL: 'sext_to_i32' -; ALL-NEXT: Classifying expressions for: @sext_to_i32 -; ALL-NEXT: %tmp = sub i32 %arg, sext (i16 ptrtoint ([0 x i8]* @global to i16) to i32) -; ALL-NEXT: --> ((-1 * (sext i16 ptrtoint ([0 x i8]* @global to i16) to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * (sext i16 ptrtoint ([0 x i8]* @global to i16) to i32)) + %arg) LoopDispositions: { %bb7: Invariant } -; ALL-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 -; ALL-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } -; ALL-NEXT: Determining loop execution counts for: @sext_to_i32 -; ALL-NEXT: Loop %bb7: Unpredictable backedge-taken count. -; ALL-NEXT: Loop %bb7: Unpredictable max backedge-taken count. -; ALL-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; PTR64_IDX64-LABEL: 'sext_to_i32' +; PTR64_IDX64-NEXT: Classifying expressions for: @sext_to_i32 +; PTR64_IDX64-NEXT: %tmp = sub i32 %arg, sext (i16 ptrtoint ([0 x i8]* @global to i16) to i32) +; PTR64_IDX64-NEXT: --> ((-1 * (sext i16 (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i16) to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * (sext i16 (trunc i64 (ptrtoint [0 x i8]* @global to i64) to i16) to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR64_IDX64-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR64_IDX64-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR64_IDX64-NEXT: Determining loop execution counts for: @sext_to_i32 +; PTR64_IDX64-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR64_IDX64-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR64_IDX64-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; +; PTR64_IDX32-LABEL: 'sext_to_i32' +; PTR64_IDX32-NEXT: Classifying expressions for: @sext_to_i32 +; PTR64_IDX32-NEXT: %tmp = sub i32 %arg, sext (i16 ptrtoint ([0 x i8]* @global to i16) to i32) +; PTR64_IDX32-NEXT: --> ((-1 * (sext i16 ptrtoint ([0 x i8]* @global to i16) to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * (sext i16 ptrtoint ([0 x i8]* @global to i16) to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR64_IDX32-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR64_IDX32-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR64_IDX32-NEXT: Determining loop execution counts for: @sext_to_i32 +; PTR64_IDX32-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR64_IDX32-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR64_IDX32-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; +; PTR16_IDX16-LABEL: 'sext_to_i32' +; PTR16_IDX16-NEXT: Classifying expressions for: @sext_to_i32 +; PTR16_IDX16-NEXT: %tmp = sub i32 %arg, sext (i16 ptrtoint ([0 x i8]* @global to i16) to i32) +; PTR16_IDX16-NEXT: --> ((-1 * (sext i16 (ptrtoint [0 x i8]* @global to i16) to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * (sext i16 (ptrtoint [0 x i8]* @global to i16) to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR16_IDX16-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR16_IDX16-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR16_IDX16-NEXT: Determining loop execution counts for: @sext_to_i32 +; PTR16_IDX16-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR16_IDX16-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR16_IDX16-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. +; +; PTR16_IDX32-LABEL: 'sext_to_i32' +; PTR16_IDX32-NEXT: Classifying expressions for: @sext_to_i32 +; PTR16_IDX32-NEXT: %tmp = sub i32 %arg, sext (i16 ptrtoint ([0 x i8]* @global to i16) to i32) +; PTR16_IDX32-NEXT: --> ((-1 * (sext i16 ptrtoint ([0 x i8]* @global to i16) to i32)) + %arg) U: full-set S: full-set Exits: ((-1 * (sext i16 ptrtoint ([0 x i8]* @global to i16) to i32)) + %arg) LoopDispositions: { %bb7: Invariant } +; PTR16_IDX32-NEXT: %tmp9 = select i1 %tmp8, i16 0, i16 1 +; PTR16_IDX32-NEXT: --> %tmp9 U: [0,2) S: [-2,2) Exits: <> LoopDispositions: { %bb7: Variant } +; PTR16_IDX32-NEXT: Determining loop execution counts for: @sext_to_i32 +; PTR16_IDX32-NEXT: Loop %bb7: Unpredictable backedge-taken count. +; PTR16_IDX32-NEXT: Loop %bb7: Unpredictable max backedge-taken count. +; PTR16_IDX32-NEXT: Loop %bb7: Unpredictable predicated backedge-taken count. ; bb: br label %bb7 @@ -338,39 +393,73 @@ } define i64 @sext_like_noop(i32 %n) { -; X64-LABEL: 'sext_like_noop' -; X64-NEXT: Classifying expressions for: @sext_like_noop -; X64-NEXT: %ii = sext i32 %i to i64 -; X64-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) -; X64-NEXT: %div = sdiv i64 55555, %ii -; X64-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 sext (i32 add (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32), i32 -1) to i64)) U: full-set S: full-set -; X64-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ] -; X64-NEXT: --> {1,+,1}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable } -; X64-NEXT: %inc = add nuw i32 %i, 1 -; X64-NEXT: --> {2,+,1}<%for.body> U: [2,0) S: [2,0) Exits: ptrtoint (i64 (i32)* @sext_like_noop to i32) LoopDispositions: { %for.body: Computable } -; X64-NEXT: Determining loop execution counts for: @sext_like_noop -; X64-NEXT: Loop %for.body: backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) -; X64-NEXT: Loop %for.body: max backedge-taken count is -1 -; X64-NEXT: Loop %for.body: Predicated backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) -; X64-NEXT: Predicates: -; X64: Loop %for.body: Trip multiple is 1 +; PTR64_IDX64-LABEL: 'sext_like_noop' +; PTR64_IDX64-NEXT: Classifying expressions for: @sext_like_noop +; PTR64_IDX64-NEXT: %ii = sext i32 %i to i64 +; PTR64_IDX64-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + (trunc i64 (ptrtoint i64 (i32)* @sext_like_noop to i64) to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) +; PTR64_IDX64-NEXT: %div = sdiv i64 55555, %ii +; PTR64_IDX64-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 sext (i32 add (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32), i32 -1) to i64)) U: full-set S: full-set +; PTR64_IDX64-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ] +; PTR64_IDX64-NEXT: --> {1,+,1}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + (trunc i64 (ptrtoint i64 (i32)* @sext_like_noop to i64) to i32)) LoopDispositions: { %for.body: Computable } +; PTR64_IDX64-NEXT: %inc = add nuw i32 %i, 1 +; PTR64_IDX64-NEXT: --> {2,+,1}<%for.body> U: [2,0) S: [2,0) Exits: (trunc i64 (ptrtoint i64 (i32)* @sext_like_noop to i64) to i32) LoopDispositions: { %for.body: Computable } +; PTR64_IDX64-NEXT: Determining loop execution counts for: @sext_like_noop +; PTR64_IDX64-NEXT: Loop %for.body: backedge-taken count is (-2 + (trunc i64 (ptrtoint i64 (i32)* @sext_like_noop to i64) to i32)) +; PTR64_IDX64-NEXT: Loop %for.body: max backedge-taken count is -1 +; PTR64_IDX64-NEXT: Loop %for.body: Predicated backedge-taken count is (-2 + (trunc i64 (ptrtoint i64 (i32)* @sext_like_noop to i64) to i32)) +; PTR64_IDX64-NEXT: Predicates: +; PTR64_IDX64: Loop %for.body: Trip multiple is 1 +; +; PTR64_IDX32-LABEL: 'sext_like_noop' +; PTR64_IDX32-NEXT: Classifying expressions for: @sext_like_noop +; PTR64_IDX32-NEXT: %ii = sext i32 %i to i64 +; PTR64_IDX32-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) +; PTR64_IDX32-NEXT: %div = sdiv i64 55555, %ii +; PTR64_IDX32-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 sext (i32 add (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32), i32 -1) to i64)) U: full-set S: full-set +; PTR64_IDX32-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ] +; PTR64_IDX32-NEXT: --> {1,+,1}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable } +; PTR64_IDX32-NEXT: %inc = add nuw i32 %i, 1 +; PTR64_IDX32-NEXT: --> {2,+,1}<%for.body> U: [2,0) S: [2,0) Exits: ptrtoint (i64 (i32)* @sext_like_noop to i32) LoopDispositions: { %for.body: Computable } +; PTR64_IDX32-NEXT: Determining loop execution counts for: @sext_like_noop +; PTR64_IDX32-NEXT: Loop %for.body: backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) +; PTR64_IDX32-NEXT: Loop %for.body: max backedge-taken count is -1 +; PTR64_IDX32-NEXT: Loop %for.body: Predicated backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) +; PTR64_IDX32-NEXT: Predicates: +; PTR64_IDX32: Loop %for.body: Trip multiple is 1 +; +; PTR16_IDX16-LABEL: 'sext_like_noop' +; PTR16_IDX16-NEXT: Classifying expressions for: @sext_like_noop +; PTR16_IDX16-NEXT: %ii = sext i32 %i to i64 +; PTR16_IDX16-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i64)) U: [-1,65535) S: [-1,65535) +; PTR16_IDX16-NEXT: %div = sdiv i64 55555, %ii +; PTR16_IDX16-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 add (i64 zext (i16 ptrtoint (i64 (i32)* @sext_like_noop to i16) to i64), i64 -1)) U: full-set S: full-set +; PTR16_IDX16-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ] +; PTR16_IDX16-NEXT: --> {1,+,1}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i32)) LoopDispositions: { %for.body: Computable } +; PTR16_IDX16-NEXT: %inc = add nuw i32 %i, 1 +; PTR16_IDX16-NEXT: --> {2,+,1}<%for.body> U: [2,0) S: [2,0) Exits: (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i32) LoopDispositions: { %for.body: Computable } +; PTR16_IDX16-NEXT: Determining loop execution counts for: @sext_like_noop +; PTR16_IDX16-NEXT: Loop %for.body: backedge-taken count is (-2 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i32)) +; PTR16_IDX16-NEXT: Loop %for.body: max backedge-taken count is -1 +; PTR16_IDX16-NEXT: Loop %for.body: Predicated backedge-taken count is (-2 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i32)) +; PTR16_IDX16-NEXT: Predicates: +; PTR16_IDX16: Loop %for.body: Trip multiple is 1 ; -; X32-LABEL: 'sext_like_noop' -; X32-NEXT: Classifying expressions for: @sext_like_noop -; X32-NEXT: %ii = sext i32 %i to i64 -; X32-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (sext i32 ptrtoint (i64 (i32)* @sext_like_noop to i32) to i64)) U: [-1,65535) S: [-65537,65535) -; X32-NEXT: %div = sdiv i64 55555, %ii -; X32-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 add (i64 sext (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32) to i64), i64 -1)) U: full-set S: full-set -; X32-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ] -; X32-NEXT: --> {1,+,1}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable } -; X32-NEXT: %inc = add nuw i32 %i, 1 -; X32-NEXT: --> {2,+,1}<%for.body> U: [2,0) S: [2,0) Exits: ptrtoint (i64 (i32)* @sext_like_noop to i32) LoopDispositions: { %for.body: Computable } -; X32-NEXT: Determining loop execution counts for: @sext_like_noop -; X32-NEXT: Loop %for.body: backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) -; X32-NEXT: Loop %for.body: max backedge-taken count is -1 -; X32-NEXT: Loop %for.body: Predicated backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) -; X32-NEXT: Predicates: -; X32: Loop %for.body: Trip multiple is 1 +; PTR16_IDX32-LABEL: 'sext_like_noop' +; PTR16_IDX32-NEXT: Classifying expressions for: @sext_like_noop +; PTR16_IDX32-NEXT: %ii = sext i32 %i to i64 +; PTR16_IDX32-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (sext i32 ptrtoint (i64 (i32)* @sext_like_noop to i32) to i64)) U: [-1,65535) S: [-65537,65535) +; PTR16_IDX32-NEXT: %div = sdiv i64 55555, %ii +; PTR16_IDX32-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 add (i64 sext (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32) to i64), i64 -1)) U: full-set S: full-set +; PTR16_IDX32-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ] +; PTR16_IDX32-NEXT: --> {1,+,1}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable } +; PTR16_IDX32-NEXT: %inc = add nuw i32 %i, 1 +; PTR16_IDX32-NEXT: --> {2,+,1}<%for.body> U: [2,0) S: [2,0) Exits: ptrtoint (i64 (i32)* @sext_like_noop to i32) LoopDispositions: { %for.body: Computable } +; PTR16_IDX32-NEXT: Determining loop execution counts for: @sext_like_noop +; PTR16_IDX32-NEXT: Loop %for.body: backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) +; PTR16_IDX32-NEXT: Loop %for.body: max backedge-taken count is -1 +; PTR16_IDX32-NEXT: Loop %for.body: Predicated backedge-taken count is (-2 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) +; PTR16_IDX32-NEXT: Predicates: +; PTR16_IDX32: Loop %for.body: Trip multiple is 1 ; entry: %cmp6 = icmp sgt i32 %n, 1 diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll --- a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll +++ b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll @@ -16,25 +16,25 @@ ; X64-LABEL: 'ptrtoint' ; X64-NEXT: Classifying expressions for: @ptrtoint ; X64-NEXT: %p0 = ptrtoint i8* %in to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* %in to i64) U: full-set S: full-set ; X64-NEXT: %p1 = ptrtoint i8* %in to i32 -; X64-NEXT: --> %p1 U: full-set S: full-set +; X64-NEXT: --> (trunc i64 (ptrtoint i8* %in to i64) to i32) U: full-set S: full-set ; X64-NEXT: %p2 = ptrtoint i8* %in to i16 -; X64-NEXT: --> %p2 U: full-set S: full-set +; X64-NEXT: --> (trunc i64 (ptrtoint i8* %in to i64) to i16) U: full-set S: full-set ; X64-NEXT: %p3 = ptrtoint i8* %in to i128 -; X64-NEXT: --> %p3 U: [0,18446744073709551616) S: [-18446744073709551616,18446744073709551616) +; X64-NEXT: --> (zext i64 (ptrtoint i8* %in to i64) to i128) U: [0,18446744073709551616) S: [0,18446744073709551616) ; X64-NEXT: Determining loop execution counts for: @ptrtoint ; ; X32-LABEL: 'ptrtoint' ; X32-NEXT: Classifying expressions for: @ptrtoint ; X32-NEXT: %p0 = ptrtoint i8* %in to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* %in to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: %p1 = ptrtoint i8* %in to i32 -; X32-NEXT: --> %p1 U: full-set S: full-set +; X32-NEXT: --> (ptrtoint i8* %in to i32) U: full-set S: full-set ; X32-NEXT: %p2 = ptrtoint i8* %in to i16 -; X32-NEXT: --> %p2 U: full-set S: full-set +; X32-NEXT: --> (trunc i32 (ptrtoint i8* %in to i32) to i16) U: full-set S: full-set ; X32-NEXT: %p3 = ptrtoint i8* %in to i128 -; X32-NEXT: --> %p3 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* %in to i32) to i128) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint ; %p0 = ptrtoint i8* %in to i64 @@ -53,25 +53,25 @@ ; X64-LABEL: 'ptrtoint_as1' ; X64-NEXT: Classifying expressions for: @ptrtoint_as1 ; X64-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8 addrspace(1)* %in to i64) U: full-set S: full-set ; X64-NEXT: %p1 = ptrtoint i8 addrspace(1)* %in to i32 -; X64-NEXT: --> %p1 U: full-set S: full-set +; X64-NEXT: --> (trunc i64 (ptrtoint i8 addrspace(1)* %in to i64) to i32) U: full-set S: full-set ; X64-NEXT: %p2 = ptrtoint i8 addrspace(1)* %in to i16 -; X64-NEXT: --> %p2 U: full-set S: full-set +; X64-NEXT: --> (trunc i64 (ptrtoint i8 addrspace(1)* %in to i64) to i16) U: full-set S: full-set ; X64-NEXT: %p3 = ptrtoint i8 addrspace(1)* %in to i128 -; X64-NEXT: --> %p3 U: [0,18446744073709551616) S: [-18446744073709551616,18446744073709551616) +; X64-NEXT: --> (zext i64 (ptrtoint i8 addrspace(1)* %in to i64) to i128) U: [0,18446744073709551616) S: [0,18446744073709551616) ; X64-NEXT: Determining loop execution counts for: @ptrtoint_as1 ; ; X32-LABEL: 'ptrtoint_as1' ; X32-NEXT: Classifying expressions for: @ptrtoint_as1 ; X32-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8 addrspace(1)* %in to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: %p1 = ptrtoint i8 addrspace(1)* %in to i32 -; X32-NEXT: --> %p1 U: full-set S: full-set +; X32-NEXT: --> (ptrtoint i8 addrspace(1)* %in to i32) U: full-set S: full-set ; X32-NEXT: %p2 = ptrtoint i8 addrspace(1)* %in to i16 -; X32-NEXT: --> %p2 U: full-set S: full-set +; X32-NEXT: --> (trunc i32 (ptrtoint i8 addrspace(1)* %in to i32) to i16) U: full-set S: full-set ; X32-NEXT: %p3 = ptrtoint i8 addrspace(1)* %in to i128 -; X32-NEXT: --> %p3 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8 addrspace(1)* %in to i32) to i128) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_as1 ; %p0 = ptrtoint i8 addrspace(1)* %in to i64 @@ -92,7 +92,7 @@ ; X64-NEXT: %in_casted = bitcast i8* %in to float* ; X64-NEXT: --> %in U: full-set S: full-set ; X64-NEXT: %p0 = ptrtoint float* %in_casted to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* %in to i64) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast ; ; X32-LABEL: 'ptrtoint_of_bitcast' @@ -100,7 +100,7 @@ ; X32-NEXT: %in_casted = bitcast i8* %in to float* ; X32-NEXT: --> %in U: full-set S: full-set ; X32-NEXT: %p0 = ptrtoint float* %in_casted to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* %in to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast ; %in_casted = bitcast i8* %in to float* @@ -116,7 +116,7 @@ ; X64-NEXT: %in_casted = addrspacecast i8* %in to i8 addrspace(1)* ; X64-NEXT: --> %in_casted U: full-set S: full-set ; X64-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in_casted to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8 addrspace(1)* %in_casted to i64) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_addrspacecast ; ; X32-LABEL: 'ptrtoint_of_addrspacecast' @@ -124,7 +124,7 @@ ; X32-NEXT: %in_casted = addrspacecast i8* %in to i8 addrspace(1)* ; X32-NEXT: --> %in_casted U: full-set S: full-set ; X32-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in_casted to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8 addrspace(1)* %in_casted to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_addrspacecast ; %in_casted = addrspacecast i8* %in to i8 addrspace(1)* @@ -140,7 +140,7 @@ ; X64-NEXT: %in_casted = inttoptr i64 %in to i8* ; X64-NEXT: --> %in_casted U: full-set S: full-set ; X64-NEXT: %p0 = ptrtoint i8* %in_casted to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* %in_casted to i64) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_inttoptr ; ; X32-LABEL: 'ptrtoint_of_inttoptr' @@ -148,7 +148,7 @@ ; X32-NEXT: %in_casted = inttoptr i64 %in to i8* ; X32-NEXT: --> %in_casted U: full-set S: full-set ; X32-NEXT: %p0 = ptrtoint i8* %in_casted to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* %in_casted to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_inttoptr ; %in_casted = inttoptr i64 %in to i8* @@ -162,7 +162,7 @@ ; ALL-LABEL: 'ptrtoint_of_nullptr' ; ALL-NEXT: Classifying expressions for: @ptrtoint_of_nullptr ; ALL-NEXT: %p0 = ptrtoint i8* null to i64 -; ALL-NEXT: --> %p0 U: [0,1) S: [-1,1) +; ALL-NEXT: --> 0 U: [0,1) S: [0,1) ; ALL-NEXT: Determining loop execution counts for: @ptrtoint_of_nullptr ; %p0 = ptrtoint i8* null to i64 @@ -172,11 +172,17 @@ ; A constant inttoptr argument of an ptrtoint is still bad. define void @ptrtoint_of_constantexpr_inttoptr(i64* %out0) { -; ALL-LABEL: 'ptrtoint_of_constantexpr_inttoptr' -; ALL-NEXT: Classifying expressions for: @ptrtoint_of_constantexpr_inttoptr -; ALL-NEXT: %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64 -; ALL-NEXT: --> %p0 U: [42,43) S: [-64,64) -; ALL-NEXT: Determining loop execution counts for: @ptrtoint_of_constantexpr_inttoptr +; X64-LABEL: 'ptrtoint_of_constantexpr_inttoptr' +; X64-NEXT: Classifying expressions for: @ptrtoint_of_constantexpr_inttoptr +; X64-NEXT: %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64 +; X64-NEXT: --> (ptrtoint i8* inttoptr (i64 42 to i8*) to i64) U: [42,43) S: [-64,64) +; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_constantexpr_inttoptr +; +; X32-LABEL: 'ptrtoint_of_constantexpr_inttoptr' +; X32-NEXT: Classifying expressions for: @ptrtoint_of_constantexpr_inttoptr +; X32-NEXT: %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64 +; X32-NEXT: --> (zext i32 (ptrtoint i8* inttoptr (i64 42 to i8*) to i32) to i64) U: [42,43) S: [0,4294967296) +; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_constantexpr_inttoptr ; %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64 store i64 %p0, i64* %out0 @@ -190,7 +196,7 @@ ; X64-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42 ; X64-NEXT: --> (42 + %in) U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808) ; X64-NEXT: %p0 = ptrtoint i8* %in_adj to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* (42 + %in) to i64) U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808) ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_gep ; ; X32-LABEL: 'ptrtoint_of_gep' @@ -198,7 +204,7 @@ ; X32-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42 ; X32-NEXT: --> (42 + %in) U: [-2147483606,-2147483648) S: [-2147483606,-2147483648) ; X32-NEXT: %p0 = ptrtoint i8* %in_adj to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* (42 + %in) to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_gep ; %in_adj = getelementptr inbounds i8, i8* %in, i64 42 @@ -220,7 +226,7 @@ ; X64-NEXT: %i7 = getelementptr inbounds i32, i32* %in, i64 %i6 ; X64-NEXT: --> {%in,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64)) + %in) LoopDispositions: { %loop: Computable } ; X64-NEXT: %i8 = ptrtoint i32* %i7 to i64 -; X64-NEXT: --> %i8 U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; X64-NEXT: --> (ptrtoint i32* {%in,+,4}<%loop> to i64) U: full-set S: full-set Exits: (ptrtoint i32* (-4 + (4 * (zext i32 %count to i64)) + %in) to i64) LoopDispositions: { %loop: Computable } ; X64-NEXT: %i9 = add nuw nsw i64 %i6, 1 ; X64-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: (zext i32 %count to i64) LoopDispositions: { %loop: Computable } ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_addrec @@ -239,7 +245,7 @@ ; X32-NEXT: %i7 = getelementptr inbounds i32, i32* %in, i64 %i6 ; X32-NEXT: --> {%in,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %in) LoopDispositions: { %loop: Computable } ; X32-NEXT: %i8 = ptrtoint i32* %i7 to i64 -; X32-NEXT: --> %i8 U: [0,4294967296) S: [-4294967296,4294967296) Exits: <> LoopDispositions: { %loop: Variant } +; X32-NEXT: --> (zext i32 (ptrtoint i32* {%in,+,4}<%loop> to i32) to i64) U: [0,4294967296) S: [0,4294967296) Exits: (zext i32 (ptrtoint i32* (-4 + (4 * %count) + %in) to i32) to i64) LoopDispositions: { %loop: Computable } ; X32-NEXT: %i9 = add nuw nsw i64 %i6, 1 ; X32-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: (zext i32 %count to i64) LoopDispositions: { %loop: Computable } ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_addrec @@ -274,7 +280,7 @@ ; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X64-NEXT: --> (%in0 umax %in1) U: full-set S: full-set ; X64-NEXT: %p0 = ptrtoint i8* %s to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* (%in0 umax %in1) to i64) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_umax ; ; X32-LABEL: 'ptrtoint_of_umax' @@ -282,7 +288,7 @@ ; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X32-NEXT: --> (%in0 umax %in1) U: full-set S: full-set ; X32-NEXT: %p0 = ptrtoint i8* %s to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* (%in0 umax %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_umax ; %c = icmp uge i8* %in0, %in1 @@ -298,7 +304,7 @@ ; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X64-NEXT: --> (%in0 smax %in1) U: full-set S: full-set ; X64-NEXT: %p0 = ptrtoint i8* %s to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* (%in0 smax %in1) to i64) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_smax ; ; X32-LABEL: 'ptrtoint_of_smax' @@ -306,7 +312,7 @@ ; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X32-NEXT: --> (%in0 smax %in1) U: full-set S: full-set ; X32-NEXT: %p0 = ptrtoint i8* %s to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* (%in0 smax %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_smax ; %c = icmp sge i8* %in0, %in1 @@ -322,7 +328,7 @@ ; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X64-NEXT: --> (%in0 umin %in1) U: full-set S: full-set ; X64-NEXT: %p0 = ptrtoint i8* %s to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* (%in0 umin %in1) to i64) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_umin ; ; X32-LABEL: 'ptrtoint_of_umin' @@ -330,7 +336,7 @@ ; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X32-NEXT: --> (%in0 umin %in1) U: full-set S: full-set ; X32-NEXT: %p0 = ptrtoint i8* %s to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* (%in0 umin %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_umin ; %c = icmp ule i8* %in0, %in1 @@ -346,7 +352,7 @@ ; X64-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X64-NEXT: --> (%in0 smin %in1) U: full-set S: full-set ; X64-NEXT: %p0 = ptrtoint i8* %s to i64 -; X64-NEXT: --> %p0 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* (%in0 smin %in1) to i64) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_smin ; ; X32-LABEL: 'ptrtoint_of_smin' @@ -354,7 +360,7 @@ ; X32-NEXT: %s = select i1 %c, i8* %in0, i8* %in1 ; X32-NEXT: --> (%in0 smin %in1) U: full-set S: full-set ; X32-NEXT: %p0 = ptrtoint i8* %s to i64 -; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* (%in0 smin %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_smin ; %c = icmp sle i8* %in0, %in1 @@ -372,17 +378,17 @@ ; X64-LABEL: 'pr46786_c26_char' ; X64-NEXT: Classifying expressions for: @pr46786_c26_char ; X64-NEXT: %i4 = ptrtoint i8* %arg to i64 -; X64-NEXT: --> %i4 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* %arg to i64) U: full-set S: full-set ; X64-NEXT: %i7 = phi i8* [ %arg, %bb3 ], [ %i14, %bb6 ] ; X64-NEXT: --> {%arg,+,1}<%bb6> U: full-set S: full-set Exits: (-1 + %arg1) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i8 = load i8, i8* %i7, align 1 ; X64-NEXT: --> %i8 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X64-NEXT: %i9 = ptrtoint i8* %i7 to i64 -; X64-NEXT: --> %i9 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X64-NEXT: --> (ptrtoint i8* {%arg,+,1}<%bb6> to i64) U: full-set S: full-set Exits: (ptrtoint i8* (-1 + %arg1) to i64) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i10 = sub i64 %i9, %i4 -; X64-NEXT: --> ((-1 * %i4) + %i9) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X64-NEXT: --> ((-1 * (ptrtoint i8* %arg to i64)) + (ptrtoint i8* {%arg,+,1}<%bb6> to i64)) U: full-set S: full-set Exits: ((-1 * (ptrtoint i8* %arg to i64)) + (ptrtoint i8* (-1 + %arg1) to i64)) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i11 = getelementptr inbounds i8, i8* %arg2, i64 %i10 -; X64-NEXT: --> ((-1 * %i4) + %i9 + %arg2) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X64-NEXT: --> ((-1 * (ptrtoint i8* %arg to i64)) + (ptrtoint i8* {%arg,+,1}<%bb6> to i64) + %arg2) U: full-set S: full-set Exits: ((-1 * (ptrtoint i8* %arg to i64)) + (ptrtoint i8* (-1 + %arg1) to i64) + %arg2) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i12 = load i8, i8* %i11, align 1 ; X64-NEXT: --> %i12 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X64-NEXT: %i13 = add i8 %i12, %i8 @@ -399,17 +405,17 @@ ; X32-LABEL: 'pr46786_c26_char' ; X32-NEXT: Classifying expressions for: @pr46786_c26_char ; X32-NEXT: %i4 = ptrtoint i8* %arg to i64 -; X32-NEXT: --> %i4 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* %arg to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: %i7 = phi i8* [ %arg, %bb3 ], [ %i14, %bb6 ] ; X32-NEXT: --> {%arg,+,1}<%bb6> U: full-set S: full-set Exits: (-1 + %arg1) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i8 = load i8, i8* %i7, align 1 ; X32-NEXT: --> %i8 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X32-NEXT: %i9 = ptrtoint i8* %i7 to i64 -; X32-NEXT: --> %i9 U: [0,4294967296) S: [-4294967296,4294967296) Exits: <> LoopDispositions: { %bb6: Variant } +; X32-NEXT: --> (zext i32 (ptrtoint i8* {%arg,+,1}<%bb6> to i32) to i64) U: [0,4294967296) S: [0,4294967296) Exits: (zext i32 (ptrtoint i8* (-1 + %arg1) to i32) to i64) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i10 = sub i64 %i9, %i4 -; X32-NEXT: --> ((-1 * %i4) + %i9) U: [-4294967295,4294967296) S: [-8589934591,8589934592) Exits: <> LoopDispositions: { %bb6: Variant } +; X32-NEXT: --> ((zext i32 (ptrtoint i8* {%arg,+,1}<%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i8* %arg to i32) to i64))) U: [-4294967295,4294967296) S: [-4294967295,4294967296) Exits: ((zext i32 (ptrtoint i8* (-1 + %arg1) to i32) to i64) + (-1 * (zext i32 (ptrtoint i8* %arg to i32) to i64))) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i11 = getelementptr inbounds i8, i8* %arg2, i64 %i10 -; X32-NEXT: --> ((trunc i64 %i9 to i32) + (-1 * (trunc i64 %i4 to i32)) + %arg2) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X32-NEXT: --> ((-1 * (ptrtoint i8* %arg to i32)) + (ptrtoint i8* {%arg,+,1}<%bb6> to i32) + %arg2) U: full-set S: full-set Exits: ((-1 * (ptrtoint i8* %arg to i32)) + (ptrtoint i8* (-1 + %arg1) to i32) + %arg2) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i12 = load i8, i8* %i11, align 1 ; X32-NEXT: --> %i12 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X32-NEXT: %i13 = add i8 %i12, %i8 @@ -457,19 +463,19 @@ ; X64-LABEL: 'pr46786_c26_int' ; X64-NEXT: Classifying expressions for: @pr46786_c26_int ; X64-NEXT: %i4 = ptrtoint i32* %arg to i64 -; X64-NEXT: --> %i4 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i32* %arg to i64) U: full-set S: full-set ; X64-NEXT: %i7 = phi i32* [ %arg, %bb3 ], [ %i15, %bb6 ] ; X64-NEXT: --> {%arg,+,4}<%bb6> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i8 = load i32, i32* %i7, align 4 ; X64-NEXT: --> %i8 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X64-NEXT: %i9 = ptrtoint i32* %i7 to i64 -; X64-NEXT: --> %i9 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X64-NEXT: --> (ptrtoint i32* {%arg,+,4}<%bb6> to i64) U: full-set S: full-set Exits: (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i10 = sub i64 %i9, %i4 -; X64-NEXT: --> ((-1 * %i4) + %i9) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X64-NEXT: --> ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<%bb6> to i64)) U: full-set S: full-set Exits: ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64)) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i11 = ashr exact i64 %i10, 2 -; X64-NEXT: --> (((((-1 * %i4) + %i9) smax ((-1 * %i9) + %i4)) /u 4) * (1 smin (-1 smax ((-1 * %i4) + %i9)))) U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: <> LoopDispositions: { %bb6: Variant } +; X64-NEXT: --> (((((-1 * (ptrtoint i32* {%arg,+,4}<%bb6> to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<%bb6> to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<%bb6> to i64))))) U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: (((((-1 * (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64))))) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 -; X64-NEXT: --> ((4 * ((((-1 * %i4) + %i9) smax ((-1 * %i9) + %i4)) /u 4) * (1 smin (-1 smax ((-1 * %i4) + %i9)))) + %arg2) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X64-NEXT: --> ((4 * ((((-1 * (ptrtoint i32* {%arg,+,4}<%bb6> to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<%bb6> to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<%bb6> to i64))))) + %arg2) U: full-set S: full-set Exits: ((4 * ((((-1 * (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i64))))) + %arg2) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i13 = load i32, i32* %i12, align 4 ; X64-NEXT: --> %i13 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X64-NEXT: %i14 = add nsw i32 %i13, %i8 @@ -486,19 +492,19 @@ ; X32-LABEL: 'pr46786_c26_int' ; X32-NEXT: Classifying expressions for: @pr46786_c26_int ; X32-NEXT: %i4 = ptrtoint i32* %arg to i64 -; X32-NEXT: --> %i4 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i32* %arg to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: %i7 = phi i32* [ %arg, %bb3 ], [ %i15, %bb6 ] ; X32-NEXT: --> {%arg,+,4}<%bb6> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i8 = load i32, i32* %i7, align 4 ; X32-NEXT: --> %i8 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X32-NEXT: %i9 = ptrtoint i32* %i7 to i64 -; X32-NEXT: --> %i9 U: [0,4294967296) S: [-4294967296,4294967296) Exits: <> LoopDispositions: { %bb6: Variant } +; X32-NEXT: --> (zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64) U: [0,4294967296) S: [0,4294967296) Exits: (zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i10 = sub i64 %i9, %i4 -; X32-NEXT: --> ((-1 * %i4) + %i9) U: [-4294967295,4294967296) S: [-8589934591,8589934592) Exits: <> LoopDispositions: { %bb6: Variant } +; X32-NEXT: --> ((zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))) U: [-4294967295,4294967296) S: [-4294967295,4294967296) Exits: ((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i11 = ashr exact i64 %i10, 2 -; X32-NEXT: --> (((((-1 * %i4) + %i9) smax ((-1 * %i9) + %i4)) /u 4) * (1 smin (-1 smax ((-1 * %i4) + %i9)))) U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: <> LoopDispositions: { %bb6: Variant } +; X32-NEXT: --> (((((zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64)))) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64)))))) U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: (((((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64)))) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64)))))) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 -; X32-NEXT: --> ((4 * (trunc i64 (((((-1 * %i4) + %i9) smax ((-1 * %i9) + %i4)) /u 4) * (1 smin (-1 smax ((-1 * %i4) + %i9)))) to i32)) + %arg2) U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } +; X32-NEXT: --> ((4 * (trunc i64 (((((zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64)))) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* {%arg,+,4}<%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64)))))) to i32)) + %arg2) U: full-set S: full-set Exits: ((4 * (trunc i64 (((((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64)))) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64)))))) to i32)) + %arg2) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i13 = load i32, i32* %i12, align 4 ; X32-NEXT: --> %i13 U: full-set S: full-set Exits: <> LoopDispositions: { %bb6: Variant } ; X32-NEXT: %i14 = add nsw i32 %i13, %i8 @@ -543,9 +549,9 @@ ; X64-LABEL: 'ptrtoint_of_integer' ; X64-NEXT: Classifying expressions for: @ptrtoint_of_integer ; X64-NEXT: %i4 = ptrtoint i8* %arg to i64 -; X64-NEXT: --> %i4 U: full-set S: full-set +; X64-NEXT: --> (ptrtoint i8* %arg to i64) U: full-set S: full-set ; X64-NEXT: %i6 = sub i64 %i4, %arg1 -; X64-NEXT: --> ((-1 * %arg1) + %i4) U: full-set S: full-set +; X64-NEXT: --> ((-1 * %arg1) + (ptrtoint i8* %arg to i64)) U: full-set S: full-set ; X64-NEXT: %i9 = phi i64 [ 1, %bb7 ], [ %i11, %bb10 ] ; X64-NEXT: --> {1,+,1}<%bb8> U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %bb8: Computable } ; X64-NEXT: %i11 = add nuw i64 %i9, 1 @@ -553,16 +559,16 @@ ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_integer ; X64-NEXT: Loop %bb8: Unpredictable backedge-taken count. ; X64-NEXT: exit count for bb8: ***COULDNOTCOMPUTE*** -; X64-NEXT: exit count for bb10: (-2 + (-1 * %arg1) + %i4) +; X64-NEXT: exit count for bb10: (-2 + (-1 * %arg1) + (ptrtoint i8* %arg to i64)) ; X64-NEXT: Loop %bb8: max backedge-taken count is -1 ; X64-NEXT: Loop %bb8: Unpredictable predicated backedge-taken count. ; ; X32-LABEL: 'ptrtoint_of_integer' ; X32-NEXT: Classifying expressions for: @ptrtoint_of_integer ; X32-NEXT: %i4 = ptrtoint i8* %arg to i64 -; X32-NEXT: --> %i4 U: [0,4294967296) S: [-4294967296,4294967296) +; X32-NEXT: --> (zext i32 (ptrtoint i8* %arg to i32) to i64) U: [0,4294967296) S: [0,4294967296) ; X32-NEXT: %i6 = sub i64 %i4, %arg1 -; X32-NEXT: --> ((-1 * %arg1) + %i4) U: full-set S: full-set +; X32-NEXT: --> ((zext i32 (ptrtoint i8* %arg to i32) to i64) + (-1 * %arg1)) U: full-set S: full-set ; X32-NEXT: %i9 = phi i64 [ 1, %bb7 ], [ %i11, %bb10 ] ; X32-NEXT: --> {1,+,1}<%bb8> U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %bb8: Computable } ; X32-NEXT: %i11 = add nuw i64 %i9, 1 @@ -570,7 +576,7 @@ ; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_integer ; X32-NEXT: Loop %bb8: Unpredictable backedge-taken count. ; X32-NEXT: exit count for bb8: ***COULDNOTCOMPUTE*** -; X32-NEXT: exit count for bb10: (-2 + (-1 * %arg1) + %i4) +; X32-NEXT: exit count for bb10: (-2 + (zext i32 (ptrtoint i8* %arg to i32) to i64) + (-1 * %arg1)) ; X32-NEXT: Loop %bb8: max backedge-taken count is -1 ; X32-NEXT: Loop %bb8: Unpredictable predicated backedge-taken count. ; diff --git a/llvm/test/Other/constant-fold-gep.ll b/llvm/test/Other/constant-fold-gep.ll --- a/llvm/test/Other/constant-fold-gep.ll +++ b/llvm/test/Other/constant-fold-gep.ll @@ -313,31 +313,31 @@ ; TO: } ; SCEV: Classifying expressions for: @fa ; SCEV: %t = bitcast i64 mul (i64 ptrtoint (double* getelementptr (double, double* null, i32 1) to i64), i64 2310) to i64 -; SCEV: --> (2310 * sizeof(double)) +; SCEV: --> 18480 ; SCEV: Classifying expressions for: @fb ; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64) to i64 -; SCEV: --> alignof(double) +; SCEV: --> 8 ; SCEV: Classifying expressions for: @fc ; SCEV: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double, double* null, i32 1) to i64), i64 2) to i64 -; SCEV: --> (2 * sizeof(double)) +; SCEV: --> 16 ; SCEV: Classifying expressions for: @fd ; SCEV: %t = bitcast i64 mul nuw (i64 ptrtoint (double* getelementptr (double, double* null, i32 1) to i64), i64 11) to i64 -; SCEV: --> (11 * sizeof(double)) +; SCEV: --> 88 ; SCEV: Classifying expressions for: @fe ; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr ({ double, float, double, double }, { double, float, double, double }* null, i64 0, i32 2) to i64) to i64 -; SCEV: --> offsetof({ double, float, double, double }, 2) +; SCEV: --> 16 ; SCEV: Classifying expressions for: @ff ; SCEV: %t = bitcast i64 1 to i64 ; SCEV: --> 1 ; SCEV: Classifying expressions for: @fg ; SCEV: %t = bitcast i64 ptrtoint (double* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64) to i64 -; SCEV: --> alignof(double) +; SCEV: --> 8 ; SCEV: Classifying expressions for: @fh ; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64) to i64 -; SCEV: --> sizeof(i1*) +; SCEV: --> 8 ; SCEV: Classifying expressions for: @fi ; SCEV: %t = bitcast i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64) to i64 -; SCEV: --> alignof(i1*) +; SCEV: --> 8 define i64 @fa() nounwind { %t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}, {[7 x double], [7 x double]}* null, i64 11) to i64), i64 5)) to i64 @@ -408,13 +408,13 @@ ; TO: } ; SCEV: Classifying expressions for: @fM ; SCEV: %t = bitcast i64* getelementptr (i64, i64* null, i32 1) to i64* -; SCEV: --> 8 +; SCEV: --> 8 ; SCEV: Classifying expressions for: @fN ; SCEV: %t = bitcast i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1) to i64* -; SCEV: --> 8 +; SCEV: --> 8 ; SCEV: Classifying expressions for: @fO ; SCEV: %t = bitcast i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1) to i64* -; SCEV: --> 8 +; SCEV: --> 8 define i64* @fM() nounwind { %t = bitcast i64* getelementptr (i64, i64* null, i32 1) to i64* diff --git a/llvm/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll b/llvm/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll --- a/llvm/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll +++ b/llvm/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll @@ -59,20 +59,20 @@ ; CHECK-NEXT: [[TMP14:%.*]] = load i16*, i16** [[MBEGIN]], align 8 ; CHECK-NEXT: [[TMP48:%.*]] = zext i32 [[TMP16]] to i64 ; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i16, i16* [[TMP14]], i64 [[TMP48]] -; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[IDX_EXT21]], 1 +; CHECK-NEXT: [[SCEVGEP1:%.*]] = bitcast i16* [[SCEVGEP]] to i8* ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: -; CHECK-NEXT: [[LSR_IV8:%.*]] = phi [33 x i16]* [ [[TMP4:%.*]], [[FOR_BODY]] ], [ [[TMP2]], [[FOR_BODY_LR_PH]] ] -; CHECK-NEXT: [[LSR_IV2:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[TMP3]], [[FOR_BODY_LR_PH]] ] -; CHECK-NEXT: [[LSR_IV:%.*]] = phi i16* [ [[SCEVGEP1:%.*]], [[FOR_BODY]] ], [ [[SCEVGEP]], [[FOR_BODY_LR_PH]] ] +; CHECK-NEXT: [[LSR_IV8:%.*]] = phi [33 x i16]* [ [[TMP3:%.*]], [[FOR_BODY]] ], [ [[TMP2]], [[FOR_BODY_LR_PH]] ] +; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_LR_PH]] ] ; CHECK-NEXT: [[LSR_IV810:%.*]] = bitcast [33 x i16]* [[LSR_IV8]] to i16* +; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, i8* [[SCEVGEP1]], i64 [[LSR_IV]] +; CHECK-NEXT: [[UGLYGEP2:%.*]] = bitcast i8* [[UGLYGEP]] to i16* ; CHECK-NEXT: [[TMP29:%.*]] = load i16, i16* [[LSR_IV810]], align 2 -; CHECK-NEXT: store i16 [[TMP29]], i16* [[LSR_IV]], align 2 -; CHECK-NEXT: [[SCEVGEP1]] = getelementptr i16, i16* [[LSR_IV]], i64 1 -; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV2]], -2 +; CHECK-NEXT: store i16 [[TMP29]], i16* [[UGLYGEP2]], align 2 +; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], 2 ; CHECK-NEXT: [[LSR_IV_NEXT3:%.*]] = inttoptr i64 [[LSR_IV_NEXT]] to i16* ; CHECK-NEXT: [[SCEVGEP9:%.*]] = getelementptr [33 x i16], [33 x i16]* [[LSR_IV8]], i64 0, i64 1 -; CHECK-NEXT: [[TMP4]] = bitcast i16* [[SCEVGEP9]] to [33 x i16]* +; CHECK-NEXT: [[TMP3]] = bitcast i16* [[SCEVGEP9]] to [33 x i16]* ; CHECK-NEXT: [[CMP27:%.*]] = icmp eq i16* [[LSR_IV_NEXT3]], null ; CHECK-NEXT: br i1 [[CMP27]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]] ; CHECK: for.end.loopexit: diff --git a/polly/include/polly/Support/SCEVAffinator.h b/polly/include/polly/Support/SCEVAffinator.h --- a/polly/include/polly/Support/SCEVAffinator.h +++ b/polly/include/polly/Support/SCEVAffinator.h @@ -99,6 +99,7 @@ PWACtx visit(const llvm::SCEV *E); PWACtx visitConstant(const llvm::SCEVConstant *E); + PWACtx visitPtrToIntExpr(const llvm::SCEVPtrToIntExpr *E); PWACtx visitTruncateExpr(const llvm::SCEVTruncateExpr *E); PWACtx visitZeroExtendExpr(const llvm::SCEVZeroExtendExpr *E); PWACtx visitSignExtendExpr(const llvm::SCEVSignExtendExpr *E); diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp --- a/polly/lib/Support/SCEVAffinator.cpp +++ b/polly/lib/Support/SCEVAffinator.cpp @@ -266,6 +266,10 @@ isl::manage(isl_pw_aff_from_aff(isl_aff_val_on_domain(ls, v)))); } +PWACtx SCEVAffinator::visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) { + return visit(Expr->getOperand(0)); +} + PWACtx SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) { // Truncate operations are basically modulo operations, thus we can // model them that way. However, for large types we assume the operand @@ -538,8 +542,6 @@ switch (I->getOpcode()) { case Instruction::IntToPtr: return visit(SE.getSCEVAtScope(I->getOperand(0), getScope())); - case Instruction::PtrToInt: - return visit(SE.getSCEVAtScope(I->getOperand(0), getScope())); case Instruction::SDiv: return visitSDivInstruction(I); case Instruction::SRem: diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -161,6 +161,10 @@ return ValidatorResult(SCEVType::PARAM, Expr); } + class ValidatorResult visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) { + return visit(Expr->getOperand()); + } + class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) { return visitZeroExtendOrTruncateExpr(Expr, Expr->getOperand()); } @@ -444,8 +448,6 @@ switch (I->getOpcode()) { case Instruction::IntToPtr: return visit(SE.getSCEVAtScope(I->getOperand(0), Scope)); - case Instruction::PtrToInt: - return visit(SE.getSCEVAtScope(I->getOperand(0), Scope)); case Instruction::Load: return visitLoadInstruction(I, Expr); case Instruction::SDiv: diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -341,6 +341,9 @@ /// ///{ const SCEV *visitConstant(const SCEVConstant *E) { return E; } + const SCEV *visitPtrToIntExpr(const SCEVPtrToIntExpr *E) { + return SE.getPtrToIntExpr(visit(E->getOperand()), E->getType()); + } const SCEV *visitTruncateExpr(const SCEVTruncateExpr *E) { return SE.getTruncateExpr(visit(E->getOperand()), E->getType()); } diff --git a/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll b/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll --- a/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll +++ b/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll @@ -1,7 +1,12 @@ ; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s ; -; CHECK: polly.split_new_and_old: -; CHECK-NEXT: %pollysub.ptr.lhs.cast263 = ptrtoint i8* inttoptr (i64 1 to i8*) to i64 +; CHECK: if.then260: +; CHECK-NEXT: %p.4 = getelementptr inbounds i8, i8* null, i64 1 +; CHECK-NEXT: %sub.ptr.lhs.cast263 = ptrtoint i8* %p.4 to i64 +; CHECK-NEXT: %sub.ptr.sub265 = sub i64 %sub.ptr.lhs.cast263, 0 +; CHECK-NEXT: %div = udiv i64 0, %sub.ptr.sub265 +; CHECK-NEXT: %cmp268 = icmp ult i64 0, %div +; CHECK-NEXT: br i1 %cmp268, label %cond.true270, label %while.cond.region_exiting ; target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/polly/test/ScopInfo/int2ptr_ptr2int.ll b/polly/test/ScopInfo/int2ptr_ptr2int.ll --- a/polly/test/ScopInfo/int2ptr_ptr2int.ll +++ b/polly/test/ScopInfo/int2ptr_ptr2int.ll @@ -17,21 +17,24 @@ ; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; ; ; IR: polly.stmt.for.body: -; IR-NEXT: %p_tmp = ptrtoint i64* %scevgep to i64 -; IR-NEXT: %p_add = add nsw i64 %p_tmp, 1 -; IR-NEXT: %p_tmp1 = inttoptr i64 %[[r1:[a-zA-Z0-9]*]] to i64* +; IR-NEXT: %p_tmp1 = inttoptr i64 %0 to i64* ; IR-NEXT: %p_add.ptr2 = getelementptr inbounds i64, i64* %p_tmp1, i64 1 ; IR-NEXT: %p_tmp2 = ptrtoint i64* %p_add.ptr2 to i64 ; IR-NEXT: %p_arrayidx = getelementptr inbounds i64, i64* %A, i64 %p_tmp2 -; IR-NEXT: %tmp3_p_scalar_ = load i64, i64* %p_arrayidx -; IR-NEXT: %p_arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %p_add -; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %p_arrayidx3 +; IR-NEXT: %tmp3_p_scalar_ = load i64, i64* %p_arrayidx, align 8, !alias.scope !0, !noalias !2 +; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %scevgep1, align 8, !alias.scope !0, !noalias !2 ; IR-NEXT: %p_add4 = add nsw i64 %tmp4_p_scalar_, %tmp3_p_scalar_ -; IR-NEXT: store i64 %p_add4, i64* %p_arrayidx3 +; IR-NEXT: store i64 %p_add4, i64* %scevgep1, align 8, !alias.scope !0, !noalias !2 +; IR-NEXT: %polly.indvar_next = add nsw i64 %polly.indvar, 1 +; IR-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar_next, 99 +; IR-NEXT: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit ; ; IR: polly.loop_preheader: +; IR-NEXT: %0 = add i64 %val, 1 ; IR-NEXT: %scevgep = getelementptr i64, i64* %ptr, i32 1 -; IR-NEXT: %[[r1]] = add i64 %val, 1 +; IR-NEXT: %1 = ptrtoint i64* %scevgep to i32 +; IR-NEXT: %2 = add i32 %1, 1 +; IR-NEXT: %scevgep1 = getelementptr i64, i64* %A, i32 %2 ; IR-NEXT: br label %polly.loop_header ; target datalayout = "e-p:32:32:32-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/polly/test/ScopInfo/int2ptr_ptr2int_2.ll b/polly/test/ScopInfo/int2ptr_ptr2int_2.ll --- a/polly/test/ScopInfo/int2ptr_ptr2int_2.ll +++ b/polly/test/ScopInfo/int2ptr_ptr2int_2.ll @@ -21,19 +21,21 @@ ; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; ; ; IR: polly.stmt.for.body: -; IR-NEXT: %p_tmp = ptrtoint i64* %scevgep to i16 -; IR-NEXT: %p_add = add nsw i16 %p_tmp, 1 -; IR-NEXT: %p_arrayidx3 = getelementptr inbounds i64, i64* %A, i16 %p_add -; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %p_arrayidx3 -; IR-NEXT: %p_add4 = add nsw i64 %tmp4_p_scalar_, %polly.preload.tmp3.merge -; IR-NEXT: store i64 %p_add4, i64* %p_arrayidx3 +; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %scevgep13, align 8, !alias.scope !3, !noalias !4 +; IR-NEXT: %p_add4 = add nsw i64 %tmp4_p_scalar_, %polly.preload.tmp3.merge +; IR-NEXT: store i64 %p_add4, i64* %scevgep13, align 8, !alias.scope !3, !noalias !4 +; IR-NEXT: %polly.indvar_next = add nsw i64 %polly.indvar, 1 +; IR-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar_next, 99 +; IR-NEXT: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit ; ; IR: polly.loop_preheader: -; IR-NEXT: %scevgep = getelementptr i64, i64* %ptr, i16 1 ; IR-NEXT: %35 = add i16 %val, 1 +; IR-NEXT: %scevgep = getelementptr i64, i64* %ptr, i16 1 +; IR-NEXT: %36 = ptrtoint i64* %scevgep to i16 +; IR-NEXT: %37 = add i16 %36, 1 +; IR-NEXT: %scevgep13 = getelementptr i64, i64* %A, i16 %37 ; IR-NEXT: br label %polly.loop_header ; -; target datalayout = "e-p:16:16:16-m:e-i64:64-f80:128-n8:16:16:64-S128" define void @f(i64* %A, i64* %B, i64* %ptr, i16 %val) {