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 @@ -1042,17 +1042,61 @@ ID.AddPointer(Op); void *IP = nullptr; if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) - return getTruncateOrZeroExtend(S, Ty); + return getTruncateOrZeroExtend(S, Ty, Depth); - assert(!isa(Op) && - "SCEVConstant is an integer, no constant folding to do."); + assert((isa(Op) || isa(Op)) && + "We can only gen an nary expression, or an unknown here."); - // FIXME: simplifications. + Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType()); + + // If the input operand is not an unknown (and thus is an nary expression), + // sink the cast to operands, so that the operation is performed on integers, + // and we eventually end up with just an ptrtoint(unknown). + if (const SCEVNAryExpr *NaryExpr = dyn_cast(Op)) { + SmallVector NewOps; + NewOps.reserve(NaryExpr->getNumOperands()); + for (const SCEV *Op : NaryExpr->operands()) + NewOps.push_back(Op->getType()->isPointerTy() + ? getPtrToIntExpr(Op, IntPtrTy, Depth + 1) + : Op); + const SCEV *NewNaryExpr = nullptr; + switch (SCEVTypes SCEVType = NaryExpr->getSCEVType()) { + case scAddExpr: + NewNaryExpr = getAddExpr(NewOps, NaryExpr->getNoWrapFlags(), Depth + 1); + break; + case scAddRecExpr: + NewNaryExpr = + getAddRecExpr(NewOps, cast(NaryExpr)->getLoop(), + NaryExpr->getNoWrapFlags()); + break; + case scUMaxExpr: + case scSMaxExpr: + case scUMinExpr: + case scSMinExpr: + NewNaryExpr = getMinMaxExpr(SCEVType, NewOps); + break; + + case scMulExpr: + NewNaryExpr = getMulExpr(NewOps, NaryExpr->getNoWrapFlags(), Depth + 1); + break; + case scUDivExpr: + NewNaryExpr = getUDivExpr(NewOps[0], NewOps[1]); + break; + case scConstant: + case scTruncate: + case scZeroExtend: + case scSignExtend: + case scPtrToInt: + case scUnknown: + case scCouldNotCompute: + llvm_unreachable("We can't get these types here."); + } + return getTruncateOrZeroExtend(NewNaryExpr, Ty, Depth); + } // 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 " @@ -1061,7 +1105,7 @@ SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); - return getTruncateOrZeroExtend(S, Ty); + return getTruncateOrZeroExtend(S, Ty, Depth); } const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, Type *Ty, 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 @@ -196,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: --> (ptrtoint i8* (42 + %in) to i64) U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808) +; X64-NEXT: --> (42 + (ptrtoint i8* %in to i64)) U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808) ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_gep ; ; X32-LABEL: 'ptrtoint_of_gep' @@ -204,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: --> (zext i32 (ptrtoint i8* (42 + %in) to i32) to i64) U: [0,4294967296) S: [0,4294967296) +; X32-NEXT: --> (zext i32 (42 + (ptrtoint i8* %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 @@ -226,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: --> (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: --> {(ptrtoint i32* %in to i64),+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64)) + (ptrtoint i32* %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 @@ -245,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: --> (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: --> (zext i32 {(ptrtoint i32* %in to i32),+,4}<%loop> to i64) U: [0,4294967296) S: [0,4294967296) Exits: (zext i32 (-4 + (4 * %count) + (ptrtoint i32* %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 @@ -280,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: --> (ptrtoint i8* (%in0 umax %in1) to i64) U: full-set S: full-set +; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) umax (ptrtoint i8* %in1 to i64)) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_umax ; ; X32-LABEL: 'ptrtoint_of_umax' @@ -288,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: --> (zext i32 (ptrtoint i8* (%in0 umax %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) +; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) umax (ptrtoint i8* %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 @@ -304,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: --> (ptrtoint i8* (%in0 smax %in1) to i64) U: full-set S: full-set +; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) smax (ptrtoint i8* %in1 to i64)) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_smax ; ; X32-LABEL: 'ptrtoint_of_smax' @@ -312,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: --> (zext i32 (ptrtoint i8* (%in0 smax %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) +; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) smax (ptrtoint i8* %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 @@ -328,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: --> (ptrtoint i8* (%in0 umin %in1) to i64) U: full-set S: full-set +; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) umin (ptrtoint i8* %in1 to i64)) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_umin ; ; X32-LABEL: 'ptrtoint_of_umin' @@ -336,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: --> (zext i32 (ptrtoint i8* (%in0 umin %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) +; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) umin (ptrtoint i8* %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 @@ -352,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: --> (ptrtoint i8* (%in0 smin %in1) to i64) U: full-set S: full-set +; X64-NEXT: --> ((ptrtoint i8* %in0 to i64) smin (ptrtoint i8* %in1 to i64)) U: full-set S: full-set ; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_smin ; ; X32-LABEL: 'ptrtoint_of_smin' @@ -360,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: --> (zext i32 (ptrtoint i8* (%in0 smin %in1) to i32) to i64) U: [0,4294967296) S: [0,4294967296) +; X32-NEXT: --> (zext i32 ((ptrtoint i8* %in0 to i32) smin (ptrtoint i8* %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 @@ -384,11 +384,11 @@ ; 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: --> (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: --> {(ptrtoint i8* %arg to i64),+,1}<%bb6> U: full-set S: full-set Exits: (-1 + (-1 * %arg) + (ptrtoint i8* %arg to i64) + %arg1) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i10 = sub i64 %i9, %i4 -; 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: --> {0,+,1}<%bb6> U: [0,-1) S: [0,-1) Exits: (-1 + (-1 * %arg) + %arg1) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i11 = getelementptr inbounds i8, i8* %arg2, i64 %i10 -; 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: --> {%arg2,+,1}<%bb6> U: full-set S: full-set Exits: (-1 + (-1 * %arg) + %arg1 + %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 @@ -411,11 +411,11 @@ ; 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: --> (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: --> {(zext i32 (ptrtoint i8* %arg to i32) to i64),+,1}<%bb6> U: [0,8589934590) S: [0,8589934590) Exits: ((zext i8* (-1 + (-1 * %arg) + %arg1) to i64) + (zext i32 (ptrtoint i8* %arg to i32) to i64)) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i10 = sub i64 %i9, %i4 -; 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: --> {0,+,1}<%bb6> U: [0,4294967295) S: [0,4294967295) Exits: (zext i8* (-1 + (-1 * %arg) + %arg1) to i64) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i11 = getelementptr inbounds i8, i8* %arg2, i64 %i10 -; 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: --> {%arg2,+,1}<%bb6> U: full-set S: full-set Exits: (-1 + (-1 * %arg) + %arg1 + %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 @@ -469,13 +469,13 @@ ; 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: --> (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: --> {(ptrtoint i32* %arg to i64),+,4}<%bb6> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) + (ptrtoint i32* %arg to i64)) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i10 = sub i64 %i9, %i4 -; 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: --> {0,+,4}<%bb6> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: (4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i11 = ashr exact i64 %i10, 2 -; 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: --> ((({0,+,4}<%bb6> smax {0,+,-4}<%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<%bb6>))) U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: ((((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))))) LoopDispositions: { %bb6: Computable } ; X64-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 -; 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: --> ((4 * (({0,+,4}<%bb6> smax {0,+,-4}<%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<%bb6>))) + %arg2) U: full-set S: full-set Exits: ((4 * (((4 * ((-4 + (-1 * %arg) + %arg1) /u 4)) smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))))) + %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 @@ -498,13 +498,13 @@ ; 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: --> (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: --> {(zext i32 (ptrtoint i32* %arg to i32) to i64),+,4}<%bb6> U: [0,8589934588) S: [0,8589934588) Exits: ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i10 = sub i64 %i9, %i4 -; 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: --> {0,+,4}<%bb6> U: [0,4294967293) S: [0,4294967293) Exits: (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4)) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i11 = ashr exact i64 %i10, 2 -; 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: --> ({0,+,1}<%bb6> * (1 smin {0,+,4}<%bb6>)) U: [0,1073741824) S: [0,1073741824) Exits: (((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4) * (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4)))) LoopDispositions: { %bb6: Computable } ; X32-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11 -; 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: --> (((trunc i64 (1 smin {0,+,4}<%bb6>) to i32) * {0,+,4}<%bb6>) + %arg2) U: full-set S: full-set Exits: ((4 * (trunc i64 (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))) to i32) * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %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 diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll --- a/llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll +++ b/llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll @@ -11,44 +11,42 @@ define i64 @blam(%struct.hoge* %start, %struct.hoge* %end, %struct.hoge* %ptr.2) { ; CHECK-LABEL: @blam( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[END16:%.*]] = bitcast %struct.hoge* [[END:%.*]] to i8* -; CHECK-NEXT: [[START17:%.*]] = ptrtoint %struct.hoge* [[START:%.*]] to i64 -; CHECK-NEXT: [[SCEVGEP12:%.*]] = getelementptr [[STRUCT_HOGE:%.*]], %struct.hoge* [[START]], i64 0, i32 3 -; CHECK-NEXT: [[SCEVGEP1213:%.*]] = bitcast i32* [[SCEVGEP12]] to %struct.hoge* -; CHECK-NEXT: [[TMP0:%.*]] = sub i64 0, [[START17]] -; CHECK-NEXT: [[UGLYGEP18:%.*]] = getelementptr i8, i8* [[END16]], i64 [[TMP0]] -; CHECK-NEXT: [[UGLYGEP1819:%.*]] = bitcast i8* [[UGLYGEP18]] to %struct.hoge* +; CHECK-NEXT: [[START9:%.*]] = ptrtoint %struct.hoge* [[START:%.*]] to i64 +; CHECK-NEXT: [[START6:%.*]] = bitcast %struct.hoge* [[START]] to i8* +; CHECK-NEXT: [[END8:%.*]] = bitcast %struct.hoge* [[END:%.*]] to i8* +; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint %struct.hoge* [[START]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[START9]] +; CHECK-NEXT: [[UGLYGEP10:%.*]] = getelementptr i8, i8* [[END8]], i64 [[TMP1]] ; CHECK-NEXT: br label [[LOOP_1_HEADER:%.*]] ; CHECK: loop.1.header: -; CHECK-NEXT: [[LSR_IV20:%.*]] = phi %struct.hoge* [ [[SCEVGEP21:%.*]], [[LOOP_1_HEADER]] ], [ [[UGLYGEP1819]], [[ENTRY:%.*]] ] -; CHECK-NEXT: [[LSR_IV14:%.*]] = phi %struct.hoge* [ [[SCEVGEP15:%.*]], [[LOOP_1_HEADER]] ], [ [[SCEVGEP1213]], [[ENTRY]] ] -; CHECK-NEXT: [[SCEVGEP15]] = getelementptr [[STRUCT_HOGE]], %struct.hoge* [[LSR_IV14]], i64 1 -; CHECK-NEXT: [[SCEVGEP21]] = getelementptr [[STRUCT_HOGE]], %struct.hoge* [[LSR_IV20]], i64 -1 -; CHECK-NEXT: [[EC:%.*]] = icmp eq %struct.hoge* [[SCEVGEP21]], null +; CHECK-NEXT: [[LSR_IV4:%.*]] = phi i64 [ [[LSR_IV_NEXT5:%.*]], [[LOOP_1_HEADER]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[LSR_IV_NEXT5]] = add i64 [[LSR_IV4]], -16 +; CHECK-NEXT: [[SCEVGEP11:%.*]] = getelementptr i8, i8* [[UGLYGEP10]], i64 [[LSR_IV_NEXT5]] +; CHECK-NEXT: [[SCEVGEP1112:%.*]] = bitcast i8* [[SCEVGEP11]] to %struct.hoge* +; CHECK-NEXT: [[EC:%.*]] = icmp eq %struct.hoge* [[SCEVGEP1112]], null ; CHECK-NEXT: br i1 [[EC]], label [[LOOP_2_PH:%.*]], label [[LOOP_1_HEADER]] ; CHECK: loop.2.ph: +; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[TMP0]], [[LSR_IV_NEXT5]] +; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[LSR_IV_NEXT5]], -1 +; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, i8* [[START6]], i64 [[TMP3]] +; CHECK-NEXT: [[UGLYGEP7:%.*]] = bitcast i8* [[UGLYGEP]] to %struct.hoge* ; CHECK-NEXT: br label [[LOOP_2_HEADER:%.*]] ; CHECK: loop.2.header: -; CHECK-NEXT: [[LSR_IV3:%.*]] = phi %struct.hoge* [ [[SCEVGEP4:%.*]], [[LOOP_2_LATCH:%.*]] ], [ [[SCEVGEP15]], [[LOOP_2_PH]] ] -; CHECK-NEXT: [[LSR_IV310:%.*]] = bitcast %struct.hoge* [[LSR_IV3]] to i32* -; CHECK-NEXT: [[LSR_IV37:%.*]] = bitcast %struct.hoge* [[LSR_IV3]] to i8* -; CHECK-NEXT: [[UGLYGEP8:%.*]] = getelementptr i8, i8* [[LSR_IV37]], i64 -12 -; CHECK-NEXT: [[UGLYGEP89:%.*]] = bitcast i8* [[UGLYGEP8]] to %struct.hoge* -; CHECK-NEXT: [[LSR_IV35:%.*]] = bitcast %struct.hoge* [[LSR_IV3]] to i8* -; CHECK-NEXT: [[TMP8:%.*]] = ptrtoint i32* [[LSR_IV310]] to i64 -; CHECK-NEXT: call void @use.i64(i64 [[TMP8]]) -; CHECK-NEXT: [[SCEVGEP11:%.*]] = getelementptr i32, i32* [[LSR_IV310]], i64 -1 -; CHECK-NEXT: store i32 10, i32* [[SCEVGEP11]], align 8 -; CHECK-NEXT: [[EC_2:%.*]] = icmp ugt %struct.hoge* [[UGLYGEP89]], [[PTR_2:%.*]] +; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i64 [ [[LSR_IV_NEXT2:%.*]], [[LOOP_2_LATCH:%.*]] ], [ [[TMP2]], [[LOOP_2_PH]] ] +; CHECK-NEXT: [[IV2:%.*]] = phi %struct.hoge* [ [[IV2_NEXT:%.*]], [[LOOP_2_LATCH]] ], [ [[UGLYGEP7]], [[LOOP_2_PH]] ] +; CHECK-NEXT: [[IV23:%.*]] = bitcast %struct.hoge* [[IV2]] to i32* +; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[LSR_IV1]], 12 +; CHECK-NEXT: call void @use.i64(i64 [[TMP4]]) +; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[IV23]], i64 2 +; CHECK-NEXT: store i32 10, i32* [[SCEVGEP]], align 8 +; CHECK-NEXT: [[EC_2:%.*]] = icmp ugt %struct.hoge* [[IV2]], [[PTR_2:%.*]] ; CHECK-NEXT: br i1 [[EC_2]], label [[LOOP_2_EXIT:%.*]], label [[LOOP_2_LATCH]] ; CHECK: loop.2.latch: -; CHECK-NEXT: [[SCEVGEP4]] = getelementptr [[STRUCT_HOGE]], %struct.hoge* [[LSR_IV3]], i64 1 +; CHECK-NEXT: [[IV2_NEXT]] = getelementptr inbounds [[STRUCT_HOGE:%.*]], %struct.hoge* [[IV2]], i64 1 +; CHECK-NEXT: [[LSR_IV_NEXT2]] = add i64 [[LSR_IV1]], 16 ; CHECK-NEXT: br label [[LOOP_2_HEADER]] ; CHECK: loop.2.exit: -; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, i8* [[LSR_IV35]], i64 -12 -; CHECK-NEXT: [[UGLYGEP6:%.*]] = bitcast i8* [[UGLYGEP]] to %struct.hoge* -; CHECK-NEXT: [[IV2_CAST:%.*]] = ptrtoint %struct.hoge* [[UGLYGEP6]] to i64 -; CHECK-NEXT: ret i64 [[IV2_CAST]] +; CHECK-NEXT: ret i64 [[LSR_IV1]] ; entry: br label %loop.1.header 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,25 +17,25 @@ ; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; ; ; IR: polly.stmt.for.body: -; IR-NEXT: %p_tmp1 = inttoptr i64 %0 to i64* +; IR-NEXT: %p_tmp1 = inttoptr i64 %14 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, 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: %tmp4_p_scalar_ = load i64, i64* %scevgep, 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* %scevgep1, align 8, !alias.scope !0, !noalias !2 +; IR-NEXT: store i64 %p_add4, i64* %scevgep, 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: %1 = ptrtoint i64* %scevgep to i32 -; IR-NEXT: %2 = add i32 %1, 1 -; IR-NEXT: %scevgep1 = getelementptr i64, i64* %A, i32 %2 +; IR-NEXT: %14 = add i64 %val, 1 +; IR-NEXT: %15 = ptrtoint i64* %ptr to i32 +; IR-NEXT: %16 = add i32 %15, 9 +; IR-NEXT: %scevgep = getelementptr i64, i64* %A, i32 %16 ; 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 @@ -13,7 +13,7 @@ ; ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_B[9 + val] }; -; CHECK-NEXT: Execution Context: [val, ptr] -> { : val <= 32766 } +; CHECK-NEXT: Execution Context: [val, ptr] -> { : -4097 <= val <= 4086 } ; ; CHECK: ReadAccess := [Reduction Type: +] [Scalar: 0] ; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; @@ -21,19 +21,18 @@ ; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; ; ; IR: polly.stmt.for.body: -; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %scevgep13, align 8, !alias.scope !3, !noalias !4 +; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %scevgep, 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: store i64 %p_add4, i64* %scevgep, 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: %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: %41 = add i16 %val, 1 +; IR-NEXT: %42 = ptrtoint i64* %ptr to i16 +; IR-NEXT: %43 = add i16 %42, 9 +; IR-NEXT: %scevgep = getelementptr i64, i64* %A, i16 %43 ; 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"