[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Analysis / ScalarEvolution / overflow-intrinsics.ll
blob02ed4d88c808e236f8a95a53a98d9915ffbfa4f1
1 ; RUN: opt -analyze -enable-new-pm=0 -scalar-evolution < %s | FileCheck %s
2 ; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-linux-gnu"
7 define void @f_sadd_0(i8* %a) {
8 ; CHECK-LABEL: Classifying expressions for: @f_sadd_0
9 entry:
10   br label %for.body
12 for.cond.cleanup:                                 ; preds = %cont
13   ret void
15 for.body:                                         ; preds = %entry, %cont
16 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
17 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body> U: [0,16) S: [0,16)
19   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
20   %idxprom = sext i32 %i.04 to i64
21   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
22   store i8 0, i8* %arrayidx, align 1
23   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
24   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
25   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
27 trap:                                             ; preds = %for.body
28   tail call void @llvm.trap() #2, !nosanitize !{}
29   unreachable, !nosanitize !{}
31 cont:                                             ; preds = %for.body
32   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
33   %cmp = icmp slt i32 %tmp2, 16
34   br i1 %cmp, label %for.body, label %for.cond.cleanup
35 ; CHECK: Loop %for.body: max backedge-taken count is 15
38 define void @f_sadd_1(i8* %a) {
39 ; CHECK-LABEL: Classifying expressions for: @f_sadd_1
40 entry:
41   br label %for.body
43 for.cond.cleanup:                                 ; preds = %cont
44   ret void
46 for.body:                                         ; preds = %entry, %cont
47 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
48 ; CHECK-NEXT:  -->  {0,+,1}<%for.body> U: [0,16) S: [0,16)
50 ; SCEV can prove <nsw> for the above induction variable; but it does
51 ; not bother so before it sees the sext below since it is not a 100%
52 ; obvious.
54   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
55   %idxprom = sext i32 %i.04 to i64
56   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
57   store i8 0, i8* %arrayidx, align 1
58   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
59   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
60   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
62 trap:                                             ; preds = %for.body
64   br label %cont
66 cont:                                             ; preds = %for.body
67   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
68   %cmp = icmp slt i32 %tmp2, 16
69   br i1 %cmp, label %for.body, label %for.cond.cleanup
70 ; CHECK: Loop %for.body: max backedge-taken count is 15
73 define void @f_sadd_2(i8* %a, i1* %c) {
74 ; CHECK-LABEL: Classifying expressions for: @f_sadd_2
75 entry:
76   br label %for.body
78 for.cond.cleanup:                                 ; preds = %cont
79   ret void
81 for.body:                                         ; preds = %entry, %cont
82 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
83 ; CHECK-NEXT:  -->  {0,+,1}<%for.body>
85   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
86   %idxprom = sext i32 %i.04 to i64
87   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
88   store i8 0, i8* %arrayidx, align 1
89   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
90   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
91   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
93 trap:                                             ; preds = %for.body
95   br label %cont
97 cont:                                             ; preds = %for.body
98   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
99   %cond = load volatile i1, i1* %c
100   br i1 %cond, label %for.body, label %for.cond.cleanup
103 define void @f_sadd_3(i8* %a, i1* %c) {
104 ; CHECK-LABEL: Classifying expressions for: @f_sadd_3
105 entry:
106   br label %for.body
108 for.cond.cleanup:                                 ; preds = %cont
109   ret void
111 for.body:                                         ; preds = %entry, %cont
112 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
113 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body>
115   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
116   %idxprom = sext i32 %i.04 to i64
117   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
118   store i8 0, i8* %arrayidx, align 1
119   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
120   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
121   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
122   br i1 %tmp1, label %trap, label %for.body, !nosanitize !{}
124 trap:                                             ; preds = %for.body
125   tail call void @llvm.trap() #2, !nosanitize !{}
126   unreachable, !nosanitize !{}
129 define void @f_sadd_4(i8* %a, i1* %c) {
130 ; CHECK-LABEL: Classifying expressions for: @f_sadd_4
131 entry:
132   br label %for.body
134 for.cond.cleanup:                                 ; preds = %cont
135   ret void
137 for.body:                                         ; preds = %entry, %cont
138 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
139 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body>
141   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
142   %idxprom = sext i32 %i.04 to i64
143   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
144   store i8 0, i8* %arrayidx, align 1
145   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
146   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
147   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
148   br i1 %tmp1, label %notrap, label %merge
150 notrap:
151   br label %merge
153 merge:
154   %tmp3 = extractvalue { i32, i1 } %tmp0, 1
155   br i1 %tmp3, label %trap, label %for.body, !nosanitize !{}
157 trap:                                             ; preds = %for.body
158   tail call void @llvm.trap() #2, !nosanitize !{}
159   unreachable, !nosanitize !{}
162 define void @f_sadd_may_overflow(i8* %a, i1* %c) {
163 ; CHECK-LABEL: Classifying expressions for: @f_sadd_may_overflow
164 entry:
165   br label %for.body
167 for.cond.cleanup:                                 ; preds = %cont
168   ret void
170 for.body:                                         ; preds = %entry, %cont
171 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
172 ; CHECK-NEXT:  -->  {0,+,1}<%for.body> U: full-set S: full-set
174   %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
175   %idxprom = sext i32 %i.04 to i64
176   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
177   store i8 0, i8* %arrayidx, align 1
178   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
179   %cond1 = load volatile i1, i1* %c
180   br i1 %cond1, label %trap, label %cont, !nosanitize !{}
182 trap:                                             ; preds = %for.body
183   tail call void @llvm.trap() #2, !nosanitize !{}
184   unreachable, !nosanitize !{}
186 cont:                                             ; preds = %for.body
187   %tmp1 = extractvalue { i32, i1 } %tmp0, 0
188   %cond = load volatile i1, i1* %c
189   br i1 %cond, label %for.body, label %for.cond.cleanup
192 define void @f_uadd(i8* %a) {
193 ; CHECK-LABEL: Classifying expressions for: @f_uadd
194 entry:
195   br label %for.body
197 for.cond.cleanup:                                 ; preds = %cont
198   ret void
200 for.body:                                         ; preds = %entry, %cont
201 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
202 ; CHECK-NEXT:  -->  {0,+,1}<nuw><%for.body> U: [0,16) S: [0,16)
204   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
205   %idxprom = sext i32 %i.04 to i64
206   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
207   store i8 0, i8* %arrayidx, align 1
208   %tmp0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %i.04, i32 1)
209   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
210   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
212 trap:                                             ; preds = %for.body
213   tail call void @llvm.trap(), !nosanitize !{}
214   unreachable, !nosanitize !{}
216 cont:                                             ; preds = %for.body
217   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
218   %cmp = icmp slt i32 %tmp2, 16
219   br i1 %cmp, label %for.body, label %for.cond.cleanup
220 ; CHECK: Loop %for.body: max backedge-taken count is 15
223 define void @f_ssub(i8* nocapture %a) {
224 ; CHECK-LABEL: Classifying expressions for: @f_ssub
225 entry:
226   br label %for.body
228 for.cond.cleanup:                                 ; preds = %cont
229   ret void
231 for.body:                                         ; preds = %entry, %cont
232 ; CHECK:  %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
233 ; CHECK-NEXT:  -->  {15,+,-1}<%for.body> U: [0,16) S: [0,16)
235   %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
236   %idxprom = sext i32 %i.04 to i64
237   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
238   store i8 0, i8* %arrayidx, align 1
239   %tmp0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1)
240   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
241   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
243 trap:                                             ; preds = %for.body
244   tail call void @llvm.trap(), !nosanitize !{}
245   unreachable, !nosanitize !{}
247 cont:                                             ; preds = %for.body
248   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
249   %cmp = icmp sgt i32 %tmp2, -1
250   br i1 %cmp, label %for.body, label %for.cond.cleanup
251 ; CHECK: Loop %for.body: max backedge-taken count is 15
254 define void @f_usub(i8* nocapture %a) {
255 ; CHECK-LABEL: Classifying expressions for: @f_usub
256 entry:
257   br label %for.body
259 for.cond.cleanup:                                 ; preds = %cont
260   ret void
262 for.body:                                         ; preds = %entry, %cont
263 ; CHECK:  %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
264 ; CHECK-NEXT:  -->  {15,+,-1}<%for.body> U: [0,16) S: [0,16)
266   %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
267   %idxprom = sext i32 %i.04 to i64
268   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
269   store i8 0, i8* %arrayidx, align 1
270   %tmp0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1)
271   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
272   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
274 trap:                                             ; preds = %for.body
275   tail call void @llvm.trap(), !nosanitize !{}
276   unreachable, !nosanitize !{}
278 cont:                                             ; preds = %for.body
279   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
280   %cmp = icmp sgt i32 %tmp2, -1
281   br i1 %cmp, label %for.body, label %for.cond.cleanup
282 ; CHECK: Loop %for.body: max backedge-taken count is 15
285 define i32 @f_smul(i32 %val_a, i32 %val_b) {
286 ; CHECK-LABEL: Classifying expressions for: @f_smul
287   %agg = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %val_a, i32 %val_b)
288 ; CHECK:   %mul = extractvalue { i32, i1 } %agg, 0
289 ; CHECK-NEXT:  -->  (%val_a * %val_b) U: full-set S: full-set
290   %mul = extractvalue { i32, i1 } %agg, 0
291   ret i32 %mul
294 define i32 @f_umul(i32 %val_a, i32 %val_b) {
295 ; CHECK-LABEL: Classifying expressions for: @f_umul
296   %agg = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %val_a, i32 %val_b)
297 ; CHECK:   %mul = extractvalue { i32, i1 } %agg, 0
298 ; CHECK-NEXT:  -->  (%val_a * %val_b) U: full-set S: full-set
299   %mul = extractvalue { i32, i1 } %agg, 0
300   ret i32 %mul
303 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
304 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
305 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
306 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
307 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
308 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
310 declare void @llvm.trap() #2