Skip to content

Commit 6c50e2b

Browse files
authored
[SCEV] Don't require NUW at first add when checking A+C1 < (A+C2)<nuw> (#149795)
Relax the NUW requirements for isKnownPredicateViaNoOverflow, if the second operand (Y) is an ADD. The code only simplifies the condition if C1 < C2, so if the second ADD is NUW, it doesn't matter whether the first operand also has the NUW flag, as it cannot wrap if C1 < C2. https://alive2.llvm.org/ce/z/b3dM7N PR: #149795
1 parent 39b9891 commit 6c50e2b

File tree

3 files changed

+16
-26
lines changed

3 files changed

+16
-26
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11418,8 +11418,7 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
1141811418
XNonConstOp = X;
1141911419
XFlagsPresent = ExpectedFlags;
1142011420
}
11421-
if (!isa<SCEVConstant>(XConstOp) ||
11422-
(XFlagsPresent & ExpectedFlags) != ExpectedFlags)
11421+
if (!isa<SCEVConstant>(XConstOp))
1142311422
return false;
1142411423

1142511424
if (!splitBinaryAdd(Y, YConstOp, YNonConstOp, YFlagsPresent)) {
@@ -11428,12 +11427,20 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
1142811427
YFlagsPresent = ExpectedFlags;
1142911428
}
1143011429

11431-
if (!isa<SCEVConstant>(YConstOp) ||
11432-
(YFlagsPresent & ExpectedFlags) != ExpectedFlags)
11430+
if (YNonConstOp != XNonConstOp)
1143311431
return false;
1143411432

11435-
if (YNonConstOp != XNonConstOp)
11433+
if (!isa<SCEVConstant>(YConstOp))
11434+
return false;
11435+
11436+
// When matching ADDs with NUW flags (and unsigned predicates), only the
11437+
// second ADD (with the larger constant) requires NUW.
11438+
if ((YFlagsPresent & ExpectedFlags) != ExpectedFlags)
11439+
return false;
11440+
if (ExpectedFlags != SCEV::FlagNUW &&
11441+
(XFlagsPresent & ExpectedFlags) != ExpectedFlags) {
1143611442
return false;
11443+
}
1143711444

1143811445
OutC1 = cast<SCEVConstant>(XConstOp)->getAPInt();
1143911446
OutC2 = cast<SCEVConstant>(YConstOp)->getAPInt();
@@ -11472,7 +11479,7 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
1147211479
std::swap(LHS, RHS);
1147311480
[[fallthrough]];
1147411481
case ICmpInst::ICMP_ULE:
11475-
// (X + C1)<nuw> u<= (X + C2)<nuw> for C1 u<= C2.
11482+
// (X + C1) u<= (X + C2)<nuw> for C1 u<= C2.
1147611483
if (MatchBinaryAddToConst(LHS, RHS, C1, C2, SCEV::FlagNUW) && C1.ule(C2))
1147711484
return true;
1147811485

@@ -11482,7 +11489,7 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
1148211489
std::swap(LHS, RHS);
1148311490
[[fallthrough]];
1148411491
case ICmpInst::ICMP_ULT:
11485-
// (X + C1)<nuw> u< (X + C2)<nuw> if C1 u< C2.
11492+
// (X + C1) u< (X + C2)<nuw> if C1 u< C2.
1148611493
if (MatchBinaryAddToConst(LHS, RHS, C1, C2, SCEV::FlagNUW) && C1.ult(C2))
1148711494
return true;
1148811495
break;

llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,11 @@ exit:
106106
ret void
107107
}
108108

109-
; TOOD: The loop should be safe without dependence, as all accesses to %l are
110-
; completely before the first store.
111109
define void @backward_dep_known_safe_due_to_backedge_taken_count(ptr %A) {
112110
; CHECK-LABEL: 'backward_dep_known_safe_due_to_backedge_taken_count'
113111
; CHECK-NEXT: loop:
114-
; CHECK-NEXT: Memory dependences are safe with a maximum safe vector width of 8160 bits
112+
; CHECK-NEXT: Memory dependences are safe
115113
; CHECK-NEXT: Dependences:
116-
; CHECK-NEXT: BackwardVectorizable:
117-
; CHECK-NEXT: %l = load i32, ptr %gep, align 4 ->
118-
; CHECK-NEXT: store i32 %add, ptr %gep.mul.2, align 4
119-
; CHECK-EMPTY:
120114
; CHECK-NEXT: Run-time memory checks:
121115
; CHECK-NEXT: Grouped accesses:
122116
; CHECK-EMPTY:

llvm/test/Analysis/LoopAccessAnalysis/positive-dependence-distance-different-access-sizes.ll

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,10 @@ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
88
define void @test_distance_positive_independent_via_trip_count(ptr %A) {
99
; CHECK-LABEL: 'test_distance_positive_independent_via_trip_count'
1010
; CHECK-NEXT: loop:
11-
; CHECK-NEXT: Memory dependences are safe with run-time checks
11+
; CHECK-NEXT: Memory dependences are safe
1212
; CHECK-NEXT: Dependences:
1313
; CHECK-NEXT: Run-time memory checks:
14-
; CHECK-NEXT: Check 0:
15-
; CHECK-NEXT: Comparing group GRP0:
16-
; CHECK-NEXT: %gep.A.400 = getelementptr inbounds i32, ptr %A.400, i64 %iv
17-
; CHECK-NEXT: Against group GRP1:
18-
; CHECK-NEXT: %gep.A = getelementptr inbounds i8, ptr %A, i64 %iv
1914
; CHECK-NEXT: Grouped accesses:
20-
; CHECK-NEXT: Group GRP0:
21-
; CHECK-NEXT: (Low: (400 + %A)<nuw> High: (804 + %A))
22-
; CHECK-NEXT: Member: {(400 + %A)<nuw>,+,4}<nuw><%loop>
23-
; CHECK-NEXT: Group GRP1:
24-
; CHECK-NEXT: (Low: %A High: (101 + %A))
25-
; CHECK-NEXT: Member: {%A,+,1}<nuw><%loop>
2615
; CHECK-EMPTY:
2716
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
2817
; CHECK-NEXT: SCEV assumptions:

0 commit comments

Comments
 (0)