Skip to content

Commit 8f3d169

Browse files
committed
[ScalarEvolution] Ensure backedge-taken counts are not pointers.
A backedge-taken count doesn't refer to memory; returning a pointer type is nonsense. So make sure we always return an integer. The obvious way to do this would be to just convert the operands of the icmp to integers, but that doesn't quite work out at the moment: isLoopEntryGuardedByCond currently gets confused by ptrtoint operations. So we perform the ptrtoint conversion late for lt/gt operations. The test changes are mostly innocuous. The most interesting changes are more complex SCEV expressions of the form "(-1 * (ptrtoint i8* %ptr to i64)) + %ptr)". This is expected: we can't fold this to zero because we need to preserve the pointer base. The call to isLoopEntryGuardedByCond in howFarToZero is less precise because of ptrtoint operations; this shows up in the function pr46786_c26_char in ptrtoint.ll. Fixing it here would require more complex refactoring. It should eventually be fixed by future improvements to isImpliedCond. See https://bugs.llvm.org/show_bug.cgi?id=46786 for context. Differential Revision: https://reviews.llvm.org/D103656
1 parent ad1a9d6 commit 8f3d169

File tree

13 files changed

+232
-164
lines changed

13 files changed

+232
-164
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,10 +1071,17 @@ const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op,
10711071
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
10721072
return S;
10731073

1074+
// It isn't legal for optimizations to construct new ptrtoint expressions
1075+
// for non-integral pointers.
1076+
if (getDataLayout().isNonIntegralPointerType(Op->getType()))
1077+
return getCouldNotCompute();
1078+
10741079
Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType());
10751080

1076-
// We can only model ptrtoint if SCEV's effective (integer) type
1081+
// We can only trivially model ptrtoint if SCEV's effective (integer) type
10771082
// is sufficiently wide to represent all possible pointer values.
1083+
// We could theoretically teach SCEV to truncate wider pointers, but
1084+
// that isn't implemented for now.
10781085
if (getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(Op->getType())) !=
10791086
getDataLayout().getTypeSizeInBits(IntPtrTy))
10801087
return getCouldNotCompute();
@@ -7527,6 +7534,10 @@ ScalarEvolution::ExitLimit::ExitLimit(
75277534
for (auto *PredSet : PredSetList)
75287535
for (auto *P : *PredSet)
75297536
addPredicate(P);
7537+
assert((isa<SCEVCouldNotCompute>(E) || !E->getType()->isPointerTy()) &&
7538+
"Backedge count should be int");
7539+
assert((isa<SCEVCouldNotCompute>(M) || !M->getType()->isPointerTy()) &&
7540+
"Max backedge count should be int");
75307541
}
75317542

75327543
ScalarEvolution::ExitLimit::ExitLimit(
@@ -7952,6 +7963,16 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
79527963
switch (Pred) {
79537964
case ICmpInst::ICMP_NE: { // while (X != Y)
79547965
// Convert to: while (X-Y != 0)
7966+
if (LHS->getType()->isPointerTy()) {
7967+
LHS = getLosslessPtrToIntExpr(LHS);
7968+
if (isa<SCEVCouldNotCompute>(LHS))
7969+
return LHS;
7970+
}
7971+
if (RHS->getType()->isPointerTy()) {
7972+
RHS = getLosslessPtrToIntExpr(RHS);
7973+
if (isa<SCEVCouldNotCompute>(RHS))
7974+
return RHS;
7975+
}
79557976
ExitLimit EL = howFarToZero(getMinusSCEV(LHS, RHS), L, ControlsExit,
79567977
AllowPredicates);
79577978
if (EL.hasAnyInfo()) return EL;
@@ -11515,6 +11536,22 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
1151511536
}
1151611537

1151711538
const SCEV *Start = IV->getStart();
11539+
11540+
// Preserve pointer-typed Start/RHS to pass to isLoopEntryGuardedByCond.
11541+
// Use integer-typed versions for actual computation.
11542+
const SCEV *OrigStart = Start;
11543+
const SCEV *OrigRHS = RHS;
11544+
if (Start->getType()->isPointerTy()) {
11545+
Start = getLosslessPtrToIntExpr(Start);
11546+
if (isa<SCEVCouldNotCompute>(Start))
11547+
return Start;
11548+
}
11549+
if (RHS->getType()->isPointerTy()) {
11550+
RHS = getLosslessPtrToIntExpr(RHS);
11551+
if (isa<SCEVCouldNotCompute>(RHS))
11552+
return RHS;
11553+
}
11554+
1151811555
const SCEV *End = RHS;
1151911556
// When the RHS is not invariant, we do not know the end bound of the loop and
1152011557
// cannot calculate the ExactBECount needed by ExitLimit. However, we can
@@ -11541,13 +11578,13 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
1154111578
// result is as above, and if not max(End,Start) is Start so we get a backedge
1154211579
// count of zero.
1154311580
const SCEV *BECount;
11544-
if (isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(Start, Stride), RHS))
11581+
if (isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(OrigStart, Stride), OrigRHS))
1154511582
BECount = BECountIfBackedgeTaken;
1154611583
else {
1154711584
// If we know that RHS >= Start in the context of loop, then we know that
1154811585
// max(RHS, Start) = RHS at this point.
1154911586
if (isLoopEntryGuardedByCond(
11550-
L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, RHS, Start))
11587+
L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, OrigRHS, OrigStart))
1155111588
End = RHS;
1155211589
else
1155311590
End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);
@@ -11626,6 +11663,17 @@ ScalarEvolution::howManyGreaterThans(const SCEV *LHS, const SCEV *RHS,
1162611663
End = IsSigned ? getSMinExpr(RHS, Start) : getUMinExpr(RHS, Start);
1162711664
}
1162811665

11666+
if (Start->getType()->isPointerTy()) {
11667+
Start = getLosslessPtrToIntExpr(Start);
11668+
if (isa<SCEVCouldNotCompute>(Start))
11669+
return Start;
11670+
}
11671+
if (End->getType()->isPointerTy()) {
11672+
End = getLosslessPtrToIntExpr(End);
11673+
if (isa<SCEVCouldNotCompute>(End))
11674+
return End;
11675+
}
11676+
1162911677
const SCEV *BECount = computeBECount(getMinusSCEV(Start, End), Stride);
1163011678

1163111679
APInt MaxStart = IsSigned ? getSignedRangeMax(Start)

llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -910,13 +910,13 @@ define void @crash(i8* %ptr) {
910910
; CHECK-NEXT: %incdec.ptr112 = getelementptr inbounds i8, i8* %text.addr.5, i64 -1
911911
; CHECK-NEXT: --> {(-1 + null)<nuw><nsw>,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
912912
; CHECK-NEXT: %lastout.2271 = phi i8* [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
913-
; CHECK-NEXT: --> {%ptr,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-2 + null)<nuw><nsw>,+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
913+
; CHECK-NEXT: --> {%ptr,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-2 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
914914
; CHECK-NEXT: %incdec.ptr126 = getelementptr inbounds i8, i8* %lastout.2271, i64 1
915-
; CHECK-NEXT: --> {(1 + %ptr)<nuw>,+,1}<nuw><%while.body125> U: [1,0) S: [1,0) Exits: {(-1 + null)<nuw><nsw>,+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
915+
; CHECK-NEXT: --> {(1 + %ptr)<nuw>,+,1}<nuw><%while.body125> U: [1,0) S: [1,0) Exits: {(-1 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
916916
; CHECK-NEXT: Determining loop execution counts for: @crash
917-
; CHECK-NEXT: Loop %while.body125: backedge-taken count is {(-2 + (-1 * %ptr) + null),+,-1}<nw><%while.cond111>
917+
; CHECK-NEXT: Loop %while.body125: backedge-taken count is {(-2 + (-1 * (ptrtoint i8* %ptr to i64))),+,-1}<nw><%while.cond111>
918918
; CHECK-NEXT: Loop %while.body125: max backedge-taken count is -2
919-
; CHECK-NEXT: Loop %while.body125: Predicated backedge-taken count is {(-2 + (-1 * %ptr) + null),+,-1}<nw><%while.cond111>
919+
; CHECK-NEXT: Loop %while.body125: Predicated backedge-taken count is {(-2 + (-1 * (ptrtoint i8* %ptr to i64))),+,-1}<nw><%while.cond111>
920920
; CHECK-NEXT: Predicates:
921921
; CHECK: Loop %while.body125: Trip multiple is 1
922922
; CHECK-NEXT: Loop %while.cond111: Unpredictable backedge-taken count.

llvm/test/Analysis/ScalarEvolution/no-wrap-symbolic-becount.ll

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,20 @@ exit: ; preds = %loop
9393
}
9494

9595
define void @pointer_iv_nowrap(i8* %startptr, i8* %endptr) local_unnamed_addr {
96-
; CHECK-LABEL: Classifying expressions for: @pointer_iv_nowrap
97-
; CHECK-NEXT: %init = getelementptr inbounds i8, i8* %startptr, i64 2000
98-
; CHECK-NEXT: --> (2000 + %startptr)<nuw> U: [2000,0) S: [2000,0)
99-
; CHECK-NEXT: %iv = phi i8* [ %init, %entry ], [ %iv.next, %loop ]
100-
; CHECK-NEXT: --> {(2000 + %startptr)<nuw>,+,1}<nuw><%loop> U: [2000,0) S: [2000,0)
101-
; CHECK-NEXT: %iv.next = getelementptr inbounds i8, i8* %iv, i64 1
102-
; CHECK-NEXT: --> {(2001 + %startptr)<nuw>,+,1}<nuw><%loop> U: [2001,0) S: [2001,0)
103-
104-
; CHECK-NEXT:Determining loop execution counts for: @pointer_iv_nowrap
105-
; CHECK-NEXT:Loop %loop: backedge-taken count is (-2000 + (-1 * %startptr) + ((2000 + %startptr)<nuw> umax %endptr))
106-
; CHECK-NEXT:Loop %loop: max backedge-taken count is -2001
107-
; CHECK-NEXT:Loop %loop: Predicated backedge-taken count is (-2000 + (-1 * %startptr) + ((2000 + %startptr)<nuw> umax %endptr))
96+
; CHECK-LABEL: 'pointer_iv_nowrap'
97+
; CHECK-NEXT: Classifying expressions for: @pointer_iv_nowrap
98+
; CHECK-NEXT: %init = getelementptr inbounds i8, i8* %startptr, i64 2000
99+
; CHECK-NEXT: --> (2000 + %startptr)<nuw> U: [2000,0) S: [2000,0)
100+
; CHECK-NEXT: %iv = phi i8* [ %init, %entry ], [ %iv.next, %loop ]
101+
; CHECK-NEXT: --> {(2000 + %startptr)<nuw>,+,1}<nuw><%loop> U: [2000,0) S: [2000,0) Exits: ((-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)) + %startptr) LoopDispositions: { %loop: Computable }
102+
; CHECK-NEXT: %iv.next = getelementptr inbounds i8, i8* %iv, i64 1
103+
; CHECK-NEXT: --> {(2001 + %startptr)<nuw>,+,1}<nuw><%loop> U: [2001,0) S: [2001,0) Exits: (1 + (-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)) + %startptr) LoopDispositions: { %loop: Computable }
104+
; CHECK-NEXT: Determining loop execution counts for: @pointer_iv_nowrap
105+
; CHECK-NEXT: Loop %loop: backedge-taken count is (-2000 + (-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)))
106+
; CHECK-NEXT: Loop %loop: max backedge-taken count is -2001
107+
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-2000 + (-1 * (ptrtoint i8* %startptr to i64)) + ((2000 + (ptrtoint i8* %startptr to i64))<nuw> umax (ptrtoint i8* %endptr to i64)))
108+
; CHECK-NEXT: Predicates:
109+
; CHECK: Loop %loop: Trip multiple is 1
108110
;
109111
entry:
110112
%init = getelementptr inbounds i8, i8* %startptr, i64 2000
@@ -119,3 +121,8 @@ loop:
119121
end:
120122
ret void
121123
}
124+
125+
define i32 @dummy(i32 %start, i32* %p, i32* %q) {
126+
entry:
127+
ret i32 0
128+
}

llvm/test/Analysis/ScalarEvolution/nsw.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ for.body.i.i: ; preds = %entry, %for.body.i.
102102
store i32 0, i32* %__first.addr.08.i.i, align 4
103103
%cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end
104104
br i1 %cmp.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.i.i
105-
; CHECK: Loop %for.body.i.i: backedge-taken count is ((-4 + (-1 * %begin) + %end) /u 4)
105+
; CHECK: Loop %for.body.i.i: backedge-taken count is ((-4 + (-1 * (ptrtoint i32* %begin to i64)) + (ptrtoint i32* %end to i64)) /u 4)
106106
; CHECK: Loop %for.body.i.i: max backedge-taken count is 4611686018427387903
107107
_ZSt4fillIPiiEvT_S1_RKT0_.exit: ; preds = %for.body.i.i, %entry
108108
ret void
@@ -147,7 +147,7 @@ bb7: ; preds = %bb1
147147
}
148148

149149
; CHECK-LABEL: PR12376
150-
; CHECK: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nuw> umax %arg1)) /u 4))<nuw> + %arg)
150+
; CHECK: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * (ptrtoint i32* %arg to i64)) + ((4 + (ptrtoint i32* %arg to i64))<nuw> umax (ptrtoint i32* %arg1 to i64))) /u 4))<nuw> + %arg)
151151
define void @PR12376(i32* nocapture %arg, i32* nocapture %arg1) {
152152
bb:
153153
br label %bb2

0 commit comments

Comments
 (0)