blob: fb3d816c9fab424e2bd334cd86c38e533bcf6d39 [file] [log] [blame]
Sanjoy Dasf49ca522016-05-29 00:34:42 +00001; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
2
3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4target triple = "x86_64-unknown-linux-gnu"
5
6define void @f_sadd_0(i8* %a) {
7; CHECK-LABEL: Classifying expressions for: @f_sadd_0
8entry:
9 br label %for.body
10
11for.cond.cleanup: ; preds = %cont
12 ret void
13
14for.body: ; preds = %entry, %cont
15; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
16; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body> U: [0,16) S: [0,16)
17
18 %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
19 %idxprom = sext i32 %i.04 to i64
20 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
21 store i8 0, i8* %arrayidx, align 1
22 %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
23 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
24 br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
25
26trap: ; preds = %for.body
27 tail call void @llvm.trap() #2, !nosanitize !{}
28 unreachable, !nosanitize !{}
29
30cont: ; preds = %for.body
31 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
32 %cmp = icmp slt i32 %tmp2, 16
33 br i1 %cmp, label %for.body, label %for.cond.cleanup
34; CHECK: Loop %for.body: max backedge-taken count is 15
35}
36
37define void @f_sadd_1(i8* %a) {
38; CHECK-LABEL: Classifying expressions for: @f_sadd_1
39entry:
40 br label %for.body
41
42for.cond.cleanup: ; preds = %cont
43 ret void
44
45for.body: ; preds = %entry, %cont
46; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
47; CHECK-NEXT: --> {0,+,1}<%for.body> U: [0,16) S: [0,16)
48
49; SCEV can prove <nsw> for the above induction variable; but it does
50; not bother so before it sees the sext below since it is not a 100%
51; obvious.
52
53 %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
54 %idxprom = sext i32 %i.04 to i64
55 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
56 store i8 0, i8* %arrayidx, align 1
57 %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
58 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
59 br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
60
61trap: ; preds = %for.body
62
63 br label %cont
64
65cont: ; preds = %for.body
66 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
67 %cmp = icmp slt i32 %tmp2, 16
68 br i1 %cmp, label %for.body, label %for.cond.cleanup
69; CHECK: Loop %for.body: max backedge-taken count is 15
70}
71
72define void @f_sadd_2(i8* %a, i1* %c) {
73; CHECK-LABEL: Classifying expressions for: @f_sadd_2
74entry:
75 br label %for.body
76
77for.cond.cleanup: ; preds = %cont
78 ret void
79
80for.body: ; preds = %entry, %cont
81; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
82; CHECK-NEXT: --> {0,+,1}<%for.body>
83
84 %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
85 %idxprom = sext i32 %i.04 to i64
86 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
87 store i8 0, i8* %arrayidx, align 1
88 %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
89 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
90 br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
91
92trap: ; preds = %for.body
93
94 br label %cont
95
96cont: ; preds = %for.body
97 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
98 %cond = load volatile i1, i1* %c
99 br i1 %cond, label %for.body, label %for.cond.cleanup
100}
101
102define void @f_sadd_3(i8* %a, i1* %c) {
103; CHECK-LABEL: Classifying expressions for: @f_sadd_3
104entry:
105 br label %for.body
106
107for.cond.cleanup: ; preds = %cont
108 ret void
109
110for.body: ; preds = %entry, %cont
111; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
112; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body>
113
114 %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
115 %idxprom = sext i32 %i.04 to i64
116 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
117 store i8 0, i8* %arrayidx, align 1
118 %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
119 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
120 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
121 br i1 %tmp1, label %trap, label %for.body, !nosanitize !{}
122
123trap: ; preds = %for.body
124 tail call void @llvm.trap() #2, !nosanitize !{}
125 unreachable, !nosanitize !{}
126}
127
128define void @f_sadd_4(i8* %a, i1* %c) {
129; CHECK-LABEL: Classifying expressions for: @f_sadd_4
130entry:
131 br label %for.body
132
133for.cond.cleanup: ; preds = %cont
134 ret void
135
136for.body: ; preds = %entry, %cont
137; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
138; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body>
139
140 %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
141 %idxprom = sext i32 %i.04 to i64
142 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
143 store i8 0, i8* %arrayidx, align 1
144 %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
145 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
146 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
147 br i1 %tmp1, label %notrap, label %merge
148
149notrap:
150 br label %merge
151
152merge:
153 %tmp3 = extractvalue { i32, i1 } %tmp0, 1
154 br i1 %tmp3, label %trap, label %for.body, !nosanitize !{}
155
156trap: ; preds = %for.body
157 tail call void @llvm.trap() #2, !nosanitize !{}
158 unreachable, !nosanitize !{}
159}
160
161define void @f_sadd_may_overflow(i8* %a, i1* %c) {
162; CHECK-LABEL: Classifying expressions for: @f_sadd_may_overflow
163entry:
164 br label %for.body
165
166for.cond.cleanup: ; preds = %cont
167 ret void
168
169for.body: ; preds = %entry, %cont
170; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
171; CHECK-NEXT: --> {0,+,1}<%for.body> U: full-set S: full-set
172
173 %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
174 %idxprom = sext i32 %i.04 to i64
175 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
176 store i8 0, i8* %arrayidx, align 1
177 %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
178 %cond1 = load volatile i1, i1* %c
179 br i1 %cond1, label %trap, label %cont, !nosanitize !{}
180
181trap: ; preds = %for.body
182 tail call void @llvm.trap() #2, !nosanitize !{}
183 unreachable, !nosanitize !{}
184
185cont: ; preds = %for.body
186 %tmp1 = extractvalue { i32, i1 } %tmp0, 0
187 %cond = load volatile i1, i1* %c
188 br i1 %cond, label %for.body, label %for.cond.cleanup
189}
190
191define void @f_uadd(i8* %a) {
192; CHECK-LABEL: Classifying expressions for: @f_uadd
193entry:
194 br label %for.body
195
196for.cond.cleanup: ; preds = %cont
197 ret void
198
199for.body: ; preds = %entry, %cont
200; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
201; CHECK-NEXT: --> {0,+,1}<nuw><%for.body> U: [0,16) S: [0,16)
202
203 %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
204 %idxprom = sext i32 %i.04 to i64
205 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
206 store i8 0, i8* %arrayidx, align 1
207 %tmp0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %i.04, i32 1)
208 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
209 br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
210
211trap: ; preds = %for.body
212 tail call void @llvm.trap(), !nosanitize !{}
213 unreachable, !nosanitize !{}
214
215cont: ; preds = %for.body
216 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
217 %cmp = icmp slt i32 %tmp2, 16
218 br i1 %cmp, label %for.body, label %for.cond.cleanup
219; CHECK: Loop %for.body: max backedge-taken count is 15
220}
221
222define void @f_ssub(i8* nocapture %a) {
223; CHECK-LABEL: Classifying expressions for: @f_ssub
224entry:
225 br label %for.body
226
227for.cond.cleanup: ; preds = %cont
228 ret void
229
230for.body: ; preds = %entry, %cont
231; CHECK: %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
232; CHECK-NEXT: --> {15,+,-1}<%for.body> U: [0,16) S: [0,16)
233
234 %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
235 %idxprom = sext i32 %i.04 to i64
236 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
237 store i8 0, i8* %arrayidx, align 1
238 %tmp0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1)
239 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
240 br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
241
242trap: ; preds = %for.body
243 tail call void @llvm.trap(), !nosanitize !{}
244 unreachable, !nosanitize !{}
245
246cont: ; preds = %for.body
247 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
248 %cmp = icmp sgt i32 %tmp2, -1
249 br i1 %cmp, label %for.body, label %for.cond.cleanup
250; CHECK: Loop %for.body: max backedge-taken count is 15
251}
252
253define void @f_usub(i8* nocapture %a) {
254; CHECK-LABEL: Classifying expressions for: @f_usub
255entry:
256 br label %for.body
257
258for.cond.cleanup: ; preds = %cont
259 ret void
260
261for.body: ; preds = %entry, %cont
262; CHECK: %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
263; CHECK-NEXT: --> {15,+,-1}<%for.body> U: [0,16) S: [0,16)
264
265 %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
266 %idxprom = sext i32 %i.04 to i64
267 %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
268 store i8 0, i8* %arrayidx, align 1
269 %tmp0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1)
270 %tmp1 = extractvalue { i32, i1 } %tmp0, 1
271 br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
272
273trap: ; preds = %for.body
274 tail call void @llvm.trap(), !nosanitize !{}
275 unreachable, !nosanitize !{}
276
277cont: ; preds = %for.body
278 %tmp2 = extractvalue { i32, i1 } %tmp0, 0
279 %cmp = icmp sgt i32 %tmp2, -1
280 br i1 %cmp, label %for.body, label %for.cond.cleanup
281; CHECK: Loop %for.body: max backedge-taken count is 15
282}
283
284define i32 @f_smul(i32 %val_a, i32 %val_b) {
285; CHECK-LABEL: Classifying expressions for: @f_smul
286 %agg = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %val_a, i32 %val_b)
287; CHECK: %mul = extractvalue { i32, i1 } %agg, 0
288; CHECK-NEXT: --> (%val_a * %val_b) U: full-set S: full-set
289 %mul = extractvalue { i32, i1 } %agg, 0
290 ret i32 %mul
291}
292
293define i32 @f_umul(i32 %val_a, i32 %val_b) {
294; CHECK-LABEL: Classifying expressions for: @f_umul
295 %agg = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %val_a, i32 %val_b)
296; CHECK: %mul = extractvalue { i32, i1 } %agg, 0
297; CHECK-NEXT: --> (%val_a * %val_b) U: full-set S: full-set
298 %mul = extractvalue { i32, i1 } %agg, 0
299 ret i32 %mul
300}
301
302declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
303declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
304declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
305declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
306declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
307declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
308
309declare void @llvm.trap() #2