1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[SCEV] SCEVPtrToIntExpr simplifications

If we've got an SCEVPtrToIntExpr(op), where op is not an SCEVUnknown,
we want to sink the SCEVPtrToIntExpr into an operand,
so that the operation is performed on integers,
and eventually we end up with just an `SCEVPtrToIntExpr(SCEVUnknown)`.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D89692
This commit is contained in:
Roman Lebedev 2020-10-30 09:12:49 +03:00
parent 78e0d7e6ab
commit f3176525e6
3 changed files with 102 additions and 60 deletions

View File

@ -1047,17 +1047,61 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
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<SCEVConstant>(Op) &&
"SCEVConstant is an integer, no constant folding to do.");
assert((isa<SCEVNAryExpr>(Op) || isa<SCEVUnknown>(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<SCEVNAryExpr>(Op)) {
SmallVector<const SCEV *, 2> 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<SCEVAddRecExpr>(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 "
@ -1066,7 +1110,7 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
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,

View File

@ -196,7 +196,7 @@ define void @ptrtoint_of_gep(i8* %in, i64* %out0) {
; X64-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
; X64-NEXT: --> (42 + %in)<nsw> U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808)
; X64-NEXT: %p0 = ptrtoint i8* %in_adj to i64
; X64-NEXT: --> (ptrtoint i8* (42 + %in)<nsw> to i64) U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808)
; X64-NEXT: --> (42 + (ptrtoint i8* %in to i64))<nsw> 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 @@ define void @ptrtoint_of_gep(i8* %in, i64* %out0) {
; X32-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
; X32-NEXT: --> (42 + %in)<nsw> U: [-2147483606,-2147483648) S: [-2147483606,-2147483648)
; X32-NEXT: %p0 = ptrtoint i8* %in_adj to i64
; X32-NEXT: --> (zext i32 (ptrtoint i8* (42 + %in)<nsw> to i32) to i64) U: [0,4294967296) S: [0,4294967296)
; X32-NEXT: --> (zext i32 (42 + (ptrtoint i8* %in to i32))<nsw> 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 @@ define void @ptrtoint_of_addrec(i32* %in, i32 %count) {
; X64-NEXT: %i7 = getelementptr inbounds i32, i32* %in, i64 %i6
; X64-NEXT: --> {%in,+,4}<nsw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + %in) LoopDispositions: { %loop: Computable }
; X64-NEXT: %i8 = ptrtoint i32* %i7 to i64
; X64-NEXT: --> (ptrtoint i32* {%in,+,4}<nsw><%loop> to i64) U: full-set S: full-set Exits: (ptrtoint i32* (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + %in) to i64) LoopDispositions: { %loop: Computable }
; X64-NEXT: --> {(ptrtoint i32* %in to i64),+,4}<nsw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + (ptrtoint i32* %in to i64)) LoopDispositions: { %loop: Computable }
; X64-NEXT: %i9 = add nuw nsw i64 %i6, 1
; X64-NEXT: --> {1,+,1}<nuw><%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 @@ define void @ptrtoint_of_addrec(i32* %in, i32 %count) {
; 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}<nuw><%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 @@ define void @ptrtoint_of_umax(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @ptrtoint_of_umax(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @ptrtoint_of_smax(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @ptrtoint_of_smax(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @ptrtoint_of_umin(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @ptrtoint_of_umin(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @ptrtoint_of_smin(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @ptrtoint_of_smin(i8* %in0, i8* %in1, i64* %out0) {
; 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 @@ define void @pr46786_c26_char(i8* %arg, i8* %arg1, i8* %arg2) {
; X64-NEXT: %i8 = load i8, i8* %i7, align 1
; X64-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i9 = ptrtoint i8* %i7 to i64
; X64-NEXT: --> (ptrtoint i8* {%arg,+,1}<nuw><%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}<nuw><%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}<nuw><%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}<nw><%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}<nuw><%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}<nw><%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: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i13 = add i8 %i12, %i8
@ -411,11 +411,11 @@ define void @pr46786_c26_char(i8* %arg, i8* %arg1, i8* %arg2) {
; X32-NEXT: %i8 = load i8, i8* %i7, align 1
; X32-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i9 = ptrtoint i8* %i7 to i64
; X32-NEXT: --> (zext i32 (ptrtoint i8* {%arg,+,1}<nuw><%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}<nuw><%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}<nuw><%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i8* %arg to i32) to i64))<nsw>) 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))<nsw>) LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> {0,+,1}<nw><%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}<nuw><%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: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i13 = add i8 %i12, %i8
@ -469,13 +469,13 @@ define void @pr46786_c26_int(i32* %arg, i32* %arg1, i32* %arg2) {
; X64-NEXT: %i8 = load i32, i32* %i7, align 4
; X64-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i9 = ptrtoint i32* %i7 to i64
; X64-NEXT: --> (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i64) U: full-set S: full-set Exits: (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i64) LoopDispositions: { %bb6: Computable }
; X64-NEXT: --> {(ptrtoint i32* %arg to i64),+,4}<nuw><%bb6> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + (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}<nuw><%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))<nuw> + %arg) to i64)) LoopDispositions: { %bb6: Computable }
; X64-NEXT: --> {0,+,4}<nw><%bb6> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> LoopDispositions: { %bb6: Computable }
; X64-NEXT: %i11 = ashr exact i64 %i10, 2
; X64-NEXT: --> (((((-1 * (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i64)))))<nsw> U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: (((((-1 * (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i64)))))<nsw> LoopDispositions: { %bb6: Computable }
; X64-NEXT: --> ((({0,+,4}<nw><%bb6> smax {0,+,-4}<nw><%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<nw><%bb6>)))<nsw> U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: ((((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw>)))<nsw> LoopDispositions: { %bb6: Computable }
; X64-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11
; X64-NEXT: --> ((4 * ((((-1 * (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i64))))) + %arg2)<nsw> U: full-set S: full-set Exits: ((4 * ((((-1 * (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i64)) + (ptrtoint i32* %arg to i64)) smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i64))) /u 4) * (1 smin (-1 smax ((-1 * (ptrtoint i32* %arg to i64)) + (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i64))))) + %arg2)<nsw> LoopDispositions: { %bb6: Computable }
; X64-NEXT: --> ((4 * (({0,+,4}<nw><%bb6> smax {0,+,-4}<nw><%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<nw><%bb6>))) + %arg2)<nsw> U: full-set S: full-set Exits: ((4 * (((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw>))) + %arg2)<nsw> LoopDispositions: { %bb6: Computable }
; X64-NEXT: %i13 = load i32, i32* %i12, align 4
; X64-NEXT: --> %i13 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i14 = add nsw i32 %i13, %i8
@ -498,13 +498,13 @@ define void @pr46786_c26_int(i32* %arg, i32* %arg1, i32* %arg2) {
; X32-NEXT: %i8 = load i32, i32* %i7, align 4
; X32-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i9 = ptrtoint i32* %i7 to i64
; X32-NEXT: --> (zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64) U: [0,4294967296) S: [0,4294967296) Exits: (zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64) LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> {(zext i32 (ptrtoint i32* %arg to i32) to i64),+,4}<nuw><%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))<nuw><nsw>) LoopDispositions: { %bb6: Computable }
; X32-NEXT: %i10 = sub i64 %i9, %i4
; X32-NEXT: --> ((zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>) U: [-4294967295,4294967296) S: [-4294967295,4294967296) Exits: ((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>) LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> {0,+,4}<nw><%bb6> U: [0,4294967293) S: [0,4294967293) Exits: (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw> LoopDispositions: { %bb6: Computable }
; X32-NEXT: %i11 = ashr exact i64 %i10, 2
; X32-NEXT: --> (((((zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64))<nsw>)) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>))))<nsw> U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: (((((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64))<nsw>)) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>))))<nsw> LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> ({0,+,1}<nw><%bb6> * (1 smin {0,+,4}<nuw><nsw><%bb6>))<nuw><nsw> 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))<nuw><nsw>))<nuw><nsw> LoopDispositions: { %bb6: Computable }
; X32-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11
; X32-NEXT: --> ((4 * (trunc i64 (((((zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64))<nsw>)) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* {%arg,+,4}<nuw><%bb6> to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>))))<nsw> to i32))<nsw> + %arg2)<nsw> U: full-set S: full-set Exits: ((4 * (trunc i64 (((((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>) smax ((zext i32 (ptrtoint i32* %arg to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64))<nsw>)) /u 4) * (1 smin (-1 smax ((zext i32 (ptrtoint i32* ((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) to i32) to i64) + (-1 * (zext i32 (ptrtoint i32* %arg to i32) to i64))<nsw>))))<nsw> to i32))<nsw> + %arg2)<nsw> LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> (((trunc i64 (1 smin {0,+,4}<nuw><nsw><%bb6>) to i32) * {0,+,4}<%bb6>) + %arg2)<nsw> U: full-set S: full-set Exits: ((4 * (trunc i64 (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw>) to i32) * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg2)<nsw> LoopDispositions: { %bb6: Computable }
; X32-NEXT: %i13 = load i32, i32* %i12, align 4
; X32-NEXT: --> %i13 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i14 = add nsw i32 %i13, %i8

View File

@ -11,44 +11,42 @@ target triple = "x86_64-apple-macosx10.15.0"
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