Skip to content

Commit 290a939

Browse files
committed
[SCEV] Handle nusw/nuw gep flags for addrecs
Set the nw flag is gep has any nowrap flags. Transfer the nuw flag. Also set nuw for the nusw + nneg combination.
1 parent 93ce8e1 commit 290a939

File tree

2 files changed

+153
-9
lines changed

2 files changed

+153
-9
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5882,15 +5882,17 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
58825882
Flags = setFlags(Flags, SCEV::FlagNSW);
58835883
}
58845884
} else if (GEPOperator *GEP = dyn_cast<GEPOperator>(BEValueV)) {
5885-
// If the increment is an inbounds GEP, then we know the address
5886-
// space cannot be wrapped around. We cannot make any guarantee
5887-
// about signed or unsigned overflow because pointers are
5888-
// unsigned but we may have a negative index from the base
5889-
// pointer. We can guarantee that no unsigned wrap occurs if the
5890-
// indices form a positive value.
5891-
if (GEP->isInBounds() && GEP->getOperand(0) == PN) {
5892-
Flags = setFlags(Flags, SCEV::FlagNW);
5893-
if (isKnownPositive(Accum))
5885+
if (GEP->getOperand(0) == PN) {
5886+
GEPNoWrapFlags NW = GEP->getNoWrapFlags();
5887+
// If the increment has any nowrap flags, then we know the address
5888+
// space cannot be wrapped around.
5889+
if (NW != GEPNoWrapFlags::none())
5890+
Flags = setFlags(Flags, SCEV::FlagNW);
5891+
// If the GEP is nuw or nusw with non-negative offset, we know that
5892+
// no unsigned wrap occurs. We cannot set the nsw flag as only the
5893+
// offset is treated as signed, while the base is unsigned.
5894+
if (NW.hasNoUnsignedWrap() ||
5895+
(NW.hasNoUnsignedSignedWrap() && isKnownNonNegative(Accum)))
58945896
Flags = setFlags(Flags, SCEV::FlagNUW);
58955897
}
58965898

llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,3 +2039,145 @@ define ptr @gep_nusw_nuw_missing_noundef(ptr %p, i64 %index) {
20392039
%gep = getelementptr nusw nuw i32, ptr %p, i64 %index
20402040
ret ptr %gep
20412041
}
2042+
2043+
define void @addrec_gep_inbounds_nneg(ptr %p, ptr %end) {
2044+
; CHECK-LABEL: 'addrec_gep_inbounds_nneg'
2045+
; CHECK-NEXT: Classifying expressions for: @addrec_gep_inbounds_nneg
2046+
; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]
2047+
; CHECK-NEXT: --> {%p,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }
2048+
; CHECK-NEXT: %iv.next = getelementptr inbounds i32, ptr %iv, i64 1
2049+
; CHECK-NEXT: --> {(4 + %p)<nuw>,+,4}<nuw><%loop> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }
2050+
; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_inbounds_nneg
2051+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)
2052+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 4611686018427387903
2053+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)
2054+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
2055+
;
2056+
entry:
2057+
br label %loop
2058+
loop:
2059+
%iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]
2060+
%iv.next = getelementptr inbounds i32, ptr %iv, i64 1
2061+
%cmp = icmp ne ptr %iv.next, %end
2062+
br i1 %cmp, label %loop, label %exit
2063+
exit:
2064+
ret void
2065+
}
2066+
2067+
define void @addrec_gep_inbounds_neg(ptr %p, ptr %end) {
2068+
; CHECK-LABEL: 'addrec_gep_inbounds_neg'
2069+
; CHECK-NEXT: Classifying expressions for: @addrec_gep_inbounds_neg
2070+
; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]
2071+
; CHECK-NEXT: --> {%p,+,-4}<nw><%loop> U: full-set S: full-set Exits: ((-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }
2072+
; CHECK-NEXT: %iv.next = getelementptr inbounds i32, ptr %iv, i64 -1
2073+
; CHECK-NEXT: --> {(-4 + %p),+,-4}<nw><%loop> U: full-set S: full-set Exits: (-4 + (-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }
2074+
; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_inbounds_neg
2075+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)
2076+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 4611686018427387903
2077+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)
2078+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
2079+
;
2080+
entry:
2081+
br label %loop
2082+
loop:
2083+
%iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]
2084+
%iv.next = getelementptr inbounds i32, ptr %iv, i64 -1
2085+
%cmp = icmp ne ptr %iv.next, %end
2086+
br i1 %cmp, label %loop, label %exit
2087+
exit:
2088+
ret void
2089+
}
2090+
2091+
define void @addrec_gep_nusw_nneg(ptr %p, ptr %end) {
2092+
; CHECK-LABEL: 'addrec_gep_nusw_nneg'
2093+
; CHECK-NEXT: Classifying expressions for: @addrec_gep_nusw_nneg
2094+
; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]
2095+
; CHECK-NEXT: --> {%p,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }
2096+
; CHECK-NEXT: %iv.next = getelementptr nusw i32, ptr %iv, i64 1
2097+
; CHECK-NEXT: --> {(4 + %p)<nuw>,+,4}<nuw><%loop> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }
2098+
; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nusw_nneg
2099+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)
2100+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 4611686018427387903
2101+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)
2102+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
2103+
;
2104+
entry:
2105+
br label %loop
2106+
loop:
2107+
%iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]
2108+
%iv.next = getelementptr nusw i32, ptr %iv, i64 1
2109+
%cmp = icmp ne ptr %iv.next, %end
2110+
br i1 %cmp, label %loop, label %exit
2111+
exit:
2112+
ret void
2113+
}
2114+
2115+
define void @addrec_gep_nusw_neg(ptr %p, ptr %end) {
2116+
; CHECK-LABEL: 'addrec_gep_nusw_neg'
2117+
; CHECK-NEXT: Classifying expressions for: @addrec_gep_nusw_neg
2118+
; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]
2119+
; CHECK-NEXT: --> {%p,+,-4}<nw><%loop> U: full-set S: full-set Exits: ((-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }
2120+
; CHECK-NEXT: %iv.next = getelementptr nusw i32, ptr %iv, i64 -1
2121+
; CHECK-NEXT: --> {(-4 + %p),+,-4}<nw><%loop> U: full-set S: full-set Exits: (-4 + (-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }
2122+
; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nusw_neg
2123+
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)
2124+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 4611686018427387903
2125+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)
2126+
; CHECK-NEXT: Loop %loop: Trip multiple is 1
2127+
;
2128+
entry:
2129+
br label %loop
2130+
loop:
2131+
%iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]
2132+
%iv.next = getelementptr nusw i32, ptr %iv, i64 -1
2133+
%cmp = icmp ne ptr %iv.next, %end
2134+
br i1 %cmp, label %loop, label %exit
2135+
exit:
2136+
ret void
2137+
}
2138+
2139+
define void @addrec_gep_nuw(ptr %p, ptr %end, i64 %step) {
2140+
; CHECK-LABEL: 'addrec_gep_nuw'
2141+
; CHECK-NEXT: Classifying expressions for: @addrec_gep_nuw
2142+
; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]
2143+
; CHECK-NEXT: --> {%p,+,(4 * %step)<nuw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
2144+
; CHECK-NEXT: %iv.next = getelementptr nuw i32, ptr %iv, i64 %step
2145+
; CHECK-NEXT: --> {((4 * %step)<nuw> + %p)<nuw>,+,(4 * %step)<nuw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
2146+
; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nuw
2147+
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
2148+
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
2149+
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
2150+
;
2151+
entry:
2152+
br label %loop
2153+
loop:
2154+
%iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]
2155+
%iv.next = getelementptr nuw i32, ptr %iv, i64 %step
2156+
%cmp = icmp ne ptr %iv.next, %end
2157+
br i1 %cmp, label %loop, label %exit
2158+
exit:
2159+
ret void
2160+
}
2161+
2162+
define void @addrec_gep_nusw_nuw(ptr %p, ptr %end, i64 %step) {
2163+
; CHECK-LABEL: 'addrec_gep_nusw_nuw'
2164+
; CHECK-NEXT: Classifying expressions for: @addrec_gep_nusw_nuw
2165+
; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]
2166+
; CHECK-NEXT: --> {%p,+,(4 * %step)<nuw><nsw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
2167+
; CHECK-NEXT: %iv.next = getelementptr nusw nuw i32, ptr %iv, i64 %step
2168+
; CHECK-NEXT: --> {((4 * %step)<nuw><nsw> + %p)<nuw>,+,(4 * %step)<nuw><nsw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
2169+
; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nusw_nuw
2170+
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
2171+
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
2172+
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
2173+
;
2174+
entry:
2175+
br label %loop
2176+
loop:
2177+
%iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]
2178+
%iv.next = getelementptr nusw nuw i32, ptr %iv, i64 %step
2179+
%cmp = icmp ne ptr %iv.next, %end
2180+
br i1 %cmp, label %loop, label %exit
2181+
exit:
2182+
ret void
2183+
}

0 commit comments

Comments
 (0)