• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; 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
310