xref: /aosp_15_r20/external/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -analyze -scalar-evolution | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; Positive and negative tests for inferring flags like nsw from
4*9880d681SAndroid Build Coastguard Worker; reasoning about how a poison value from overflow would trigger
5*9880d681SAndroid Build Coastguard Worker; undefined behavior.
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Workerdefine void @foo() {
8*9880d681SAndroid Build Coastguard Worker  ret void
9*9880d681SAndroid Build Coastguard Worker}
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Worker; Example where an add should get the nsw flag, so that a sext can be
12*9880d681SAndroid Build Coastguard Worker; distributed over the add.
13*9880d681SAndroid Build Coastguard Workerdefine void @test-add-nsw(float* %input, i32 %offset, i32 %numIterations) {
14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-nsw
15*9880d681SAndroid Build Coastguard Workerentry:
16*9880d681SAndroid Build Coastguard Worker  br label %loop
17*9880d681SAndroid Build Coastguard Workerloop:
18*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
21*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw>
22*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 =
25*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(sext i32 %offset to i64),+,1}<nsw>
26*9880d681SAndroid Build Coastguard Worker  %index64 = sext i32 %index32 to i64
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i64 %index64
29*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
30*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
31*9880d681SAndroid Build Coastguard Worker  call void @foo()
32*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
33*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
34*9880d681SAndroid Build Coastguard Workerexit:
35*9880d681SAndroid Build Coastguard Worker  ret void
36*9880d681SAndroid Build Coastguard Worker}
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker; Example where an add should get the nuw flag.
39*9880d681SAndroid Build Coastguard Workerdefine void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) {
40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-nuw
41*9880d681SAndroid Build Coastguard Workerentry:
42*9880d681SAndroid Build Coastguard Worker  br label %loop
43*9880d681SAndroid Build Coastguard Workerloop:
44*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
47*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nuw>
48*9880d681SAndroid Build Coastguard Worker  %index32 = add nuw i32 %i, %offset
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
51*9880d681SAndroid Build Coastguard Worker  %nexti = add nuw i32 %i, 1
52*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
53*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
54*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Workerexit:
57*9880d681SAndroid Build Coastguard Worker  ret void
58*9880d681SAndroid Build Coastguard Worker}
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Workerdefine void @test-add-nuw-from-icmp(float* %input, i32 %offset,
61*9880d681SAndroid Build Coastguard Worker                                    i32 %numIterations) {
62*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-nuw-from-icmp
63*9880d681SAndroid Build Coastguard Workerentry:
64*9880d681SAndroid Build Coastguard Worker  br label %loop
65*9880d681SAndroid Build Coastguard Workerloop:
66*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
69*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nuw>
70*9880d681SAndroid Build Coastguard Worker  %index32 = add nuw i32 %i, %offset
71*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %index32, 0
72*9880d681SAndroid Build Coastguard Worker  %cmp.idx = sext i1 %cmp to i32
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %cmp.idx
75*9880d681SAndroid Build Coastguard Worker  %nexti = add nuw i32 %i, 1
76*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
77*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
78*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Workerexit:
81*9880d681SAndroid Build Coastguard Worker  ret void
82*9880d681SAndroid Build Coastguard Worker}
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker; With no load to trigger UB from poison, we cannot infer nsw.
85*9880d681SAndroid Build Coastguard Workerdefine void @test-add-no-load(float* %input, i32 %offset, i32 %numIterations) {
86*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-no-load
87*9880d681SAndroid Build Coastguard Workerentry:
88*9880d681SAndroid Build Coastguard Worker  br label %loop
89*9880d681SAndroid Build Coastguard Workerloop:
90*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
93*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
94*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
97*9880d681SAndroid Build Coastguard Worker  %nexti = add nuw i32 %i, 1
98*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
99*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Workerexit:
102*9880d681SAndroid Build Coastguard Worker  ret void
103*9880d681SAndroid Build Coastguard Worker}
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker; The current code is only supposed to look at the loop header, so
106*9880d681SAndroid Build Coastguard Worker; it should not infer nsw in this case, as that would require looking
107*9880d681SAndroid Build Coastguard Worker; outside the loop header.
108*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header(float* %input, i32 %offset, i32 %numIterations) {
109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header
110*9880d681SAndroid Build Coastguard Workerentry:
111*9880d681SAndroid Build Coastguard Worker  br label %loop
112*9880d681SAndroid Build Coastguard Workerloop:
113*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
114*9880d681SAndroid Build Coastguard Worker  br label %loop2
115*9880d681SAndroid Build Coastguard Workerloop2:
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
118*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
119*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
122*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
123*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
124*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
125*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
126*9880d681SAndroid Build Coastguard Workerexit:
127*9880d681SAndroid Build Coastguard Worker  ret void
128*9880d681SAndroid Build Coastguard Worker}
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker; Same thing as test-add-not-header, but in this case only the load
131*9880d681SAndroid Build Coastguard Worker; instruction is outside the loop header.
132*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header2(float* %input, i32 %offset, i32 %numIterations) {
133*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header2
134*9880d681SAndroid Build Coastguard Workerentry:
135*9880d681SAndroid Build Coastguard Worker  br label %loop
136*9880d681SAndroid Build Coastguard Workerloop:
137*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
140*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw>
141*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
144*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
145*9880d681SAndroid Build Coastguard Worker  br label %loop2
146*9880d681SAndroid Build Coastguard Workerloop2:
147*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
148*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
149*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
150*9880d681SAndroid Build Coastguard Workerexit:
151*9880d681SAndroid Build Coastguard Worker  ret void
152*9880d681SAndroid Build Coastguard Worker}
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker; Similar to test-add-not-header, but in this case the load
155*9880d681SAndroid Build Coastguard Worker; instruction may not be executed.
156*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header3(float* %input, i32 %offset, i32 %numIterations,
157*9880d681SAndroid Build Coastguard Worker                                 i1* %cond_buf) {
158*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header3
159*9880d681SAndroid Build Coastguard Workerentry:
160*9880d681SAndroid Build Coastguard Worker  br label %loop
161*9880d681SAndroid Build Coastguard Workerloop:
162*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
165*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
166*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
169*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
170*9880d681SAndroid Build Coastguard Worker  %cond = load volatile i1, i1* %cond_buf
171*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %loop2, label %exit
172*9880d681SAndroid Build Coastguard Workerloop2:
173*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
174*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
175*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
176*9880d681SAndroid Build Coastguard Workerexit:
177*9880d681SAndroid Build Coastguard Worker  ret void
178*9880d681SAndroid Build Coastguard Worker}
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker; Same thing as test-add-not-header2, except we have a few extra
181*9880d681SAndroid Build Coastguard Worker; blocks.
182*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header4(float* %input, i32 %offset, i32 %numIterations) {
183*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header4
184*9880d681SAndroid Build Coastguard Workerentry:
185*9880d681SAndroid Build Coastguard Worker  br label %loop
186*9880d681SAndroid Build Coastguard Workerloop:
187*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
190*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw>
191*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
194*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
195*9880d681SAndroid Build Coastguard Worker  br label %loop3
196*9880d681SAndroid Build Coastguard Workerloop3:
197*9880d681SAndroid Build Coastguard Worker  br label %loop4
198*9880d681SAndroid Build Coastguard Workerloop4:
199*9880d681SAndroid Build Coastguard Worker  br label %loop2
200*9880d681SAndroid Build Coastguard Workerloop2:
201*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
202*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
203*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
204*9880d681SAndroid Build Coastguard Workerexit:
205*9880d681SAndroid Build Coastguard Worker  ret void
206*9880d681SAndroid Build Coastguard Worker}
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker; Demonstrate why we need a Visited set in llvm::isKnownNotFullPoison.
209*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header5(float* %input, i32 %offset) {
210*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header5
211*9880d681SAndroid Build Coastguard Workerentry:
212*9880d681SAndroid Build Coastguard Worker  br label %loop
213*9880d681SAndroid Build Coastguard Workerloop:
214*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
217*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
218*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
221*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
222*9880d681SAndroid Build Coastguard Worker  br label %loop
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Workerexit:
225*9880d681SAndroid Build Coastguard Worker  ret void
226*9880d681SAndroid Build Coastguard Worker}
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker; The call instruction makes it not guaranteed that the add will be
229*9880d681SAndroid Build Coastguard Worker; executed, since it could run forever or throw an exception, so we
230*9880d681SAndroid Build Coastguard Worker; cannot assume that the UB is realized.
231*9880d681SAndroid Build Coastguard Workerdefine void @test-add-call(float* %input, i32 %offset, i32 %numIterations) {
232*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-call
233*9880d681SAndroid Build Coastguard Workerentry:
234*9880d681SAndroid Build Coastguard Worker  br label %loop
235*9880d681SAndroid Build Coastguard Workerloop:
236*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
239*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
240*9880d681SAndroid Build Coastguard Worker  call void @foo()
241*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
244*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
245*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
246*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
247*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
248*9880d681SAndroid Build Coastguard Workerexit:
249*9880d681SAndroid Build Coastguard Worker  ret void
250*9880d681SAndroid Build Coastguard Worker}
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker; Same issue as test-add-call, but this time the call is between the
253*9880d681SAndroid Build Coastguard Worker; producer of poison and the load that consumes it.
254*9880d681SAndroid Build Coastguard Workerdefine void @test-add-call2(float* %input, i32 %offset, i32 %numIterations) {
255*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-call2
256*9880d681SAndroid Build Coastguard Workerentry:
257*9880d681SAndroid Build Coastguard Worker  br label %loop
258*9880d681SAndroid Build Coastguard Workerloop:
259*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
262*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
263*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
266*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
267*9880d681SAndroid Build Coastguard Worker  call void @foo()
268*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
269*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
270*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
271*9880d681SAndroid Build Coastguard Workerexit:
272*9880d681SAndroid Build Coastguard Worker  ret void
273*9880d681SAndroid Build Coastguard Worker}
274*9880d681SAndroid Build Coastguard Worker
275*9880d681SAndroid Build Coastguard Worker; Without inbounds, GEP does not propagate poison in the very
276*9880d681SAndroid Build Coastguard Worker; conservative approach used here.
277*9880d681SAndroid Build Coastguard Workerdefine void @test-add-no-inbounds(float* %input, i32 %offset, i32 %numIterations) {
278*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-no-inbounds
279*9880d681SAndroid Build Coastguard Workerentry:
280*9880d681SAndroid Build Coastguard Worker  br label %loop
281*9880d681SAndroid Build Coastguard Workerloop:
282*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
285*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
286*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr float, float* %input, i32 %index32
289*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
290*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
291*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
292*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
293*9880d681SAndroid Build Coastguard Workerexit:
294*9880d681SAndroid Build Coastguard Worker  ret void
295*9880d681SAndroid Build Coastguard Worker}
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker; Multiplication by a non-zero constant propagates poison if there is
298*9880d681SAndroid Build Coastguard Worker; a nuw or nsw flag on the multiplication.
299*9880d681SAndroid Build Coastguard Workerdefine void @test-add-mul-propagates(float* %input, i32 %offset, i32 %numIterations) {
300*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-mul-propagates
301*9880d681SAndroid Build Coastguard Workerentry:
302*9880d681SAndroid Build Coastguard Worker  br label %loop
303*9880d681SAndroid Build Coastguard Workerloop:
304*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
307*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw>
308*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Worker  %indexmul = mul nuw i32 %index32, 2
311*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %indexmul
312*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
313*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
314*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
315*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
316*9880d681SAndroid Build Coastguard Workerexit:
317*9880d681SAndroid Build Coastguard Worker  ret void
318*9880d681SAndroid Build Coastguard Worker}
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker; Multiplication by a non-constant should not propagate poison in the
321*9880d681SAndroid Build Coastguard Worker; very conservative approach used here.
322*9880d681SAndroid Build Coastguard Workerdefine void @test-add-mul-no-propagation(float* %input, i32 %offset, i32 %numIterations) {
323*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-mul-no-propagation
324*9880d681SAndroid Build Coastguard Workerentry:
325*9880d681SAndroid Build Coastguard Worker  br label %loop
326*9880d681SAndroid Build Coastguard Workerloop:
327*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
330*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
331*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker  %indexmul = mul nsw i32 %index32, %offset
334*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %indexmul
335*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
336*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
337*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
338*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
339*9880d681SAndroid Build Coastguard Workerexit:
340*9880d681SAndroid Build Coastguard Worker  ret void
341*9880d681SAndroid Build Coastguard Worker}
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker; Multiplication by a non-zero constant does not propagate poison
344*9880d681SAndroid Build Coastguard Worker; without a no-wrap flag.
345*9880d681SAndroid Build Coastguard Workerdefine void @test-add-mul-no-propagation2(float* %input, i32 %offset, i32 %numIterations) {
346*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-mul-no-propagation2
347*9880d681SAndroid Build Coastguard Workerentry:
348*9880d681SAndroid Build Coastguard Worker  br label %loop
349*9880d681SAndroid Build Coastguard Workerloop:
350*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
353*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
354*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker  %indexmul = mul i32 %index32, 2
357*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %indexmul
358*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
359*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
360*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
361*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
362*9880d681SAndroid Build Coastguard Workerexit:
363*9880d681SAndroid Build Coastguard Worker  ret void
364*9880d681SAndroid Build Coastguard Worker}
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker; Division by poison triggers UB.
367*9880d681SAndroid Build Coastguard Workerdefine void @test-add-div(float* %input, i32 %offset, i32 %numIterations) {
368*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-div
369*9880d681SAndroid Build Coastguard Workerentry:
370*9880d681SAndroid Build Coastguard Worker  br label %loop
371*9880d681SAndroid Build Coastguard Workerloop:
372*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker; CHECK: %j =
375*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw>
376*9880d681SAndroid Build Coastguard Worker  %j = add nsw i32 %i, %offset
377*9880d681SAndroid Build Coastguard Worker
378*9880d681SAndroid Build Coastguard Worker  %q = sdiv i32 %numIterations, %j
379*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
380*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
381*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
382*9880d681SAndroid Build Coastguard Workerexit:
383*9880d681SAndroid Build Coastguard Worker  ret void
384*9880d681SAndroid Build Coastguard Worker}
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker; Remainder of poison by non-poison divisor does not trigger UB.
387*9880d681SAndroid Build Coastguard Workerdefine void @test-add-div2(float* %input, i32 %offset, i32 %numIterations) {
388*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-div2
389*9880d681SAndroid Build Coastguard Workerentry:
390*9880d681SAndroid Build Coastguard Worker  br label %loop
391*9880d681SAndroid Build Coastguard Workerloop:
392*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
393*9880d681SAndroid Build Coastguard Worker
394*9880d681SAndroid Build Coastguard Worker; CHECK: %j =
395*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw>
396*9880d681SAndroid Build Coastguard Worker  %j = add nsw i32 %i, %offset
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker  %q = sdiv i32 %j, %numIterations
399*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
400*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
401*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
402*9880d681SAndroid Build Coastguard Workerexit:
403*9880d681SAndroid Build Coastguard Worker  ret void
404*9880d681SAndroid Build Coastguard Worker}
405*9880d681SAndroid Build Coastguard Worker
406*9880d681SAndroid Build Coastguard Worker; Store to poison address triggers UB.
407*9880d681SAndroid Build Coastguard Workerdefine void @test-add-store(float* %input, i32 %offset, i32 %numIterations) {
408*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-store
409*9880d681SAndroid Build Coastguard Workerentry:
410*9880d681SAndroid Build Coastguard Worker  br label %loop
411*9880d681SAndroid Build Coastguard Workerloop:
412*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
415*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw>
416*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %i, %offset
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
419*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
420*9880d681SAndroid Build Coastguard Worker  store float 1.0, float* %ptr, align 4
421*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
422*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
423*9880d681SAndroid Build Coastguard Workerexit:
424*9880d681SAndroid Build Coastguard Worker  ret void
425*9880d681SAndroid Build Coastguard Worker}
426*9880d681SAndroid Build Coastguard Worker
427*9880d681SAndroid Build Coastguard Worker; Three sequential adds where the middle add should have nsw. There is
428*9880d681SAndroid Build Coastguard Worker; a special case for sequential adds and this test covers that. We have to
429*9880d681SAndroid Build Coastguard Worker; put the final add first in the program since otherwise the special case
430*9880d681SAndroid Build Coastguard Worker; is not triggered, hence the strange basic block ordering.
431*9880d681SAndroid Build Coastguard Workerdefine void @test-add-twice(float* %input, i32 %offset, i32 %numIterations) {
432*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-twice
433*9880d681SAndroid Build Coastguard Workerentry:
434*9880d681SAndroid Build Coastguard Worker  br label %loop
435*9880d681SAndroid Build Coastguard Workerloop2:
436*9880d681SAndroid Build Coastguard Worker; CHECK: %seq =
437*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(2 + %offset),+,1}<nw>
438*9880d681SAndroid Build Coastguard Worker  %seq = add nsw nuw i32 %index32, 1
439*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
440*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Workerloop:
443*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
444*9880d681SAndroid Build Coastguard Worker
445*9880d681SAndroid Build Coastguard Worker  %j = add nsw i32 %i, 1
446*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
447*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(1 + %offset)<nsw>,+,1}<nsw>
448*9880d681SAndroid Build Coastguard Worker  %index32 = add nsw i32 %j, %offset
449*9880d681SAndroid Build Coastguard Worker
450*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
451*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
452*9880d681SAndroid Build Coastguard Worker  store float 1.0, float* %ptr, align 4
453*9880d681SAndroid Build Coastguard Worker  br label %loop2
454*9880d681SAndroid Build Coastguard Workerexit:
455*9880d681SAndroid Build Coastguard Worker  ret void
456*9880d681SAndroid Build Coastguard Worker}
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker; Example where a mul should get the nsw flag, so that a sext can be
459*9880d681SAndroid Build Coastguard Worker; distributed over the mul.
460*9880d681SAndroid Build Coastguard Workerdefine void @test-mul-nsw(float* %input, i32 %stride, i32 %numIterations) {
461*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-mul-nsw
462*9880d681SAndroid Build Coastguard Workerentry:
463*9880d681SAndroid Build Coastguard Worker  br label %loop
464*9880d681SAndroid Build Coastguard Workerloop:
465*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
466*9880d681SAndroid Build Coastguard Worker
467*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
468*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,%stride}<nsw>
469*9880d681SAndroid Build Coastguard Worker  %index32 = mul nsw i32 %i, %stride
470*9880d681SAndroid Build Coastguard Worker
471*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 =
472*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,(sext i32 %stride to i64)}<nsw>
473*9880d681SAndroid Build Coastguard Worker  %index64 = sext i32 %index32 to i64
474*9880d681SAndroid Build Coastguard Worker
475*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i64 %index64
476*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
477*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
478*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
479*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
480*9880d681SAndroid Build Coastguard Workerexit:
481*9880d681SAndroid Build Coastguard Worker  ret void
482*9880d681SAndroid Build Coastguard Worker}
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker; Example where a mul should get the nuw flag.
485*9880d681SAndroid Build Coastguard Workerdefine void @test-mul-nuw(float* %input, i32 %stride, i32 %numIterations) {
486*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-mul-nuw
487*9880d681SAndroid Build Coastguard Workerentry:
488*9880d681SAndroid Build Coastguard Worker  br label %loop
489*9880d681SAndroid Build Coastguard Workerloop:
490*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
493*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,%stride}<nuw>
494*9880d681SAndroid Build Coastguard Worker  %index32 = mul nuw i32 %i, %stride
495*9880d681SAndroid Build Coastguard Worker
496*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
497*9880d681SAndroid Build Coastguard Worker  %nexti = add nuw i32 %i, 1
498*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
499*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
500*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Workerexit:
503*9880d681SAndroid Build Coastguard Worker  ret void
504*9880d681SAndroid Build Coastguard Worker}
505*9880d681SAndroid Build Coastguard Worker
506*9880d681SAndroid Build Coastguard Worker; Example where a shl should get the nsw flag, so that a sext can be
507*9880d681SAndroid Build Coastguard Worker; distributed over the shl.
508*9880d681SAndroid Build Coastguard Workerdefine void @test-shl-nsw(float* %input, i32 %start, i32 %numIterations) {
509*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-shl-nsw
510*9880d681SAndroid Build Coastguard Workerentry:
511*9880d681SAndroid Build Coastguard Worker  br label %loop
512*9880d681SAndroid Build Coastguard Workerloop:
513*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
516*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(256 * %start),+,256}<nsw>
517*9880d681SAndroid Build Coastguard Worker  %index32 = shl nsw i32 %i, 8
518*9880d681SAndroid Build Coastguard Worker
519*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 =
520*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(sext i32 (256 * %start) to i64),+,256}<nsw>
521*9880d681SAndroid Build Coastguard Worker  %index64 = sext i32 %index32 to i64
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i64 %index64
524*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
525*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
526*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
527*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
528*9880d681SAndroid Build Coastguard Workerexit:
529*9880d681SAndroid Build Coastguard Worker  ret void
530*9880d681SAndroid Build Coastguard Worker}
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker; Example where a shl should get the nuw flag.
533*9880d681SAndroid Build Coastguard Workerdefine void @test-shl-nuw(float* %input, i32 %numIterations) {
534*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-shl-nuw
535*9880d681SAndroid Build Coastguard Workerentry:
536*9880d681SAndroid Build Coastguard Worker  br label %loop
537*9880d681SAndroid Build Coastguard Workerloop:
538*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
541*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,512}<nuw>
542*9880d681SAndroid Build Coastguard Worker  %index32 = shl nuw i32 %i, 9
543*9880d681SAndroid Build Coastguard Worker
544*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
545*9880d681SAndroid Build Coastguard Worker  %nexti = add nuw i32 %i, 1
546*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
547*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
548*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
549*9880d681SAndroid Build Coastguard Worker
550*9880d681SAndroid Build Coastguard Workerexit:
551*9880d681SAndroid Build Coastguard Worker  ret void
552*9880d681SAndroid Build Coastguard Worker}
553*9880d681SAndroid Build Coastguard Worker
554*9880d681SAndroid Build Coastguard Worker; Example where a sub should *not* get the nsw flag, because of how
555*9880d681SAndroid Build Coastguard Worker; scalar evolution represents A - B as A + (-B) and -B can wrap even
556*9880d681SAndroid Build Coastguard Worker; in cases where A - B does not.
557*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-no-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) {
558*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-no-nsw
559*9880d681SAndroid Build Coastguard Workerentry:
560*9880d681SAndroid Build Coastguard Worker  br label %loop
561*9880d681SAndroid Build Coastguard Workerloop:
562*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
565*9880d681SAndroid Build Coastguard Worker; CHECK: --> {((-1 * %sub) + %start),+,1}<nw>
566*9880d681SAndroid Build Coastguard Worker  %index32 = sub nsw i32 %i, %sub
567*9880d681SAndroid Build Coastguard Worker  %index64 = sext i32 %index32 to i64
568*9880d681SAndroid Build Coastguard Worker
569*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i64 %index64
570*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
571*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
572*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
573*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
574*9880d681SAndroid Build Coastguard Workerexit:
575*9880d681SAndroid Build Coastguard Worker  ret void
576*9880d681SAndroid Build Coastguard Worker}
577*9880d681SAndroid Build Coastguard Worker
578*9880d681SAndroid Build Coastguard Worker; Example where a sub should get the nsw flag as the RHS cannot be the
579*9880d681SAndroid Build Coastguard Worker; minimal signed value.
580*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) {
581*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-nsw
582*9880d681SAndroid Build Coastguard Workerentry:
583*9880d681SAndroid Build Coastguard Worker  %halfsub = ashr i32 %sub, 1
584*9880d681SAndroid Build Coastguard Worker  br label %loop
585*9880d681SAndroid Build Coastguard Workerloop:
586*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
589*9880d681SAndroid Build Coastguard Worker; CHECK: --> {((-1 * %halfsub)<nsw> + %start)<nsw>,+,1}<nsw>
590*9880d681SAndroid Build Coastguard Worker  %index32 = sub nsw i32 %i, %halfsub
591*9880d681SAndroid Build Coastguard Worker  %index64 = sext i32 %index32 to i64
592*9880d681SAndroid Build Coastguard Worker
593*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i64 %index64
594*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
595*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
596*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
597*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
598*9880d681SAndroid Build Coastguard Workerexit:
599*9880d681SAndroid Build Coastguard Worker  ret void
600*9880d681SAndroid Build Coastguard Worker}
601*9880d681SAndroid Build Coastguard Worker
602*9880d681SAndroid Build Coastguard Worker; Example where a sub should get the nsw flag, since the LHS is non-negative,
603*9880d681SAndroid Build Coastguard Worker; which implies that the RHS cannot be the minimal signed value.
604*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-nsw-lhs-non-negative(float* %input, i32 %sub, i32 %numIterations) {
605*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-nsw-lhs-non-negative
606*9880d681SAndroid Build Coastguard Workerentry:
607*9880d681SAndroid Build Coastguard Worker  br label %loop
608*9880d681SAndroid Build Coastguard Workerloop:
609*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
610*9880d681SAndroid Build Coastguard Worker
611*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
612*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(-1 * %sub),+,1}<nsw>
613*9880d681SAndroid Build Coastguard Worker  %index32 = sub nsw i32 %i, %sub
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 =
616*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(sext i32 (-1 * %sub) to i64),+,1}<nsw>
617*9880d681SAndroid Build Coastguard Worker  %index64 = sext i32 %index32 to i64
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i64 %index64
620*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
621*9880d681SAndroid Build Coastguard Worker  %f = load float, float* %ptr, align 4
622*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
623*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
624*9880d681SAndroid Build Coastguard Workerexit:
625*9880d681SAndroid Build Coastguard Worker  ret void
626*9880d681SAndroid Build Coastguard Worker}
627*9880d681SAndroid Build Coastguard Worker
628*9880d681SAndroid Build Coastguard Worker; Two adds with a sub in the middle and the sub should have nsw. There is
629*9880d681SAndroid Build Coastguard Worker; a special case for sequential adds/subs and this test covers that. We have to
630*9880d681SAndroid Build Coastguard Worker; put the final add first in the program since otherwise the special case
631*9880d681SAndroid Build Coastguard Worker; is not triggered, hence the strange basic block ordering.
632*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-with-add(float* %input, i32 %offset, i32 %numIterations) {
633*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-with-add
634*9880d681SAndroid Build Coastguard Workerentry:
635*9880d681SAndroid Build Coastguard Worker  br label %loop
636*9880d681SAndroid Build Coastguard Workerloop2:
637*9880d681SAndroid Build Coastguard Worker; CHECK: %seq =
638*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(2 + (-1 * %offset)),+,1}<nw>
639*9880d681SAndroid Build Coastguard Worker  %seq = add nsw nuw i32 %index32, 1
640*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %nexti, %numIterations
641*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %exit, label %loop
642*9880d681SAndroid Build Coastguard Worker
643*9880d681SAndroid Build Coastguard Workerloop:
644*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker  %j = add nsw i32 %i, 1
647*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 =
648*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(1 + (-1 * %offset))<nsw>,+,1}<nsw>
649*9880d681SAndroid Build Coastguard Worker  %index32 = sub nsw i32 %j, %offset
650*9880d681SAndroid Build Coastguard Worker
651*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr inbounds float, float* %input, i32 %index32
652*9880d681SAndroid Build Coastguard Worker  %nexti = add nsw i32 %i, 1
653*9880d681SAndroid Build Coastguard Worker  store float 1.0, float* %ptr, align 4
654*9880d681SAndroid Build Coastguard Worker  br label %loop2
655*9880d681SAndroid Build Coastguard Workerexit:
656*9880d681SAndroid Build Coastguard Worker  ret void
657*9880d681SAndroid Build Coastguard Worker}
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker
660*9880d681SAndroid Build Coastguard Worker; Subtraction of two recurrences. The addition in the SCEV that this
661*9880d681SAndroid Build Coastguard Worker; maps to is NSW, but the negation of the RHS does not since that
662*9880d681SAndroid Build Coastguard Worker; recurrence could be the most negative representable value.
663*9880d681SAndroid Build Coastguard Workerdefine void @subrecurrences(i32 %outer_l, i32 %inner_l, i32 %val) {
664*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @subrecurrences
665*9880d681SAndroid Build Coastguard Worker entry:
666*9880d681SAndroid Build Coastguard Worker  br label %outer
667*9880d681SAndroid Build Coastguard Worker
668*9880d681SAndroid Build Coastguard Workerouter:
669*9880d681SAndroid Build Coastguard Worker  %o_idx = phi i32 [ 0, %entry ], [ %o_idx.inc, %outer.be ]
670*9880d681SAndroid Build Coastguard Worker  %o_idx.inc = add nsw i32 %o_idx, 1
671*9880d681SAndroid Build Coastguard Worker  %cond = icmp eq i32 %o_idx, %val
672*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %inner, label %outer.be
673*9880d681SAndroid Build Coastguard Worker
674*9880d681SAndroid Build Coastguard Workerinner:
675*9880d681SAndroid Build Coastguard Worker  %i_idx = phi i32 [ 0, %outer ], [ %i_idx.inc, %inner ]
676*9880d681SAndroid Build Coastguard Worker  %i_idx.inc = add nsw i32 %i_idx, 1
677*9880d681SAndroid Build Coastguard Worker; CHECK: %v =
678*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {{[{][{]}}-1,+,-1}<nw><%outer>,+,1}<nsw><%inner>
679*9880d681SAndroid Build Coastguard Worker  %v = sub nsw i32 %i_idx, %o_idx.inc
680*9880d681SAndroid Build Coastguard Worker  %forub = udiv i32 1, %v
681*9880d681SAndroid Build Coastguard Worker  %cond2 = icmp eq i32 %i_idx, %inner_l
682*9880d681SAndroid Build Coastguard Worker  br i1 %cond2, label %outer.be, label %inner
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Workerouter.be:
685*9880d681SAndroid Build Coastguard Worker  %cond3 = icmp eq i32 %o_idx, %outer_l
686*9880d681SAndroid Build Coastguard Worker  br i1 %cond3, label %exit, label %outer
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Workerexit:
689*9880d681SAndroid Build Coastguard Worker  ret void
690*9880d681SAndroid Build Coastguard Worker}
691