Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Analysis / ScalarEvolution / overflow-intrinsics.ll
blobcd740531f83355b8e3f8f1a548415854083d19a8
1 ; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
6 define void @f_sadd_0(ptr %a) {
7 ; CHECK-LABEL: Classifying expressions for: @f_sadd_0
8 entry:
9   br label %for.body
11 for.cond.cleanup:                                 ; preds = %cont
12   ret void
14 for.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)
18   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
19   %idxprom = sext i32 %i.04 to i64
20   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
21   store i8 0, ptr %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 !{}
26 trap:                                             ; preds = %for.body
27   tail call void @llvm.trap() #2, !nosanitize !{}
28   unreachable, !nosanitize !{}
30 cont:                                             ; 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: constant max backedge-taken count is 15
37 define void @f_sadd_1(ptr %a) {
38 ; CHECK-LABEL: Classifying expressions for: @f_sadd_1
39 entry:
40   br label %for.body
42 for.cond.cleanup:                                 ; preds = %cont
43   ret void
45 for.body:                                         ; preds = %entry, %cont
46 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
47 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body> U: [0,16) S: [0,16)
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.
53   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
54   %idxprom = sext i32 %i.04 to i64
55   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
56   store i8 0, ptr %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 !{}
61 trap:                                             ; preds = %for.body
63   br label %cont
65 cont:                                             ; 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: constant max backedge-taken count is 15
72 define void @f_sadd_2(ptr %a, ptr %c) {
73 ; CHECK-LABEL: Classifying expressions for: @f_sadd_2
74 entry:
75   br label %for.body
77 for.cond.cleanup:                                 ; preds = %cont
78   ret void
80 for.body:                                         ; preds = %entry, %cont
81 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
82 ; CHECK-NEXT:  -->  {0,+,1}<%for.body>
84   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
85   %idxprom = sext i32 %i.04 to i64
86   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
87   store i8 0, ptr %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 !{}
92 trap:                                             ; preds = %for.body
94   br label %cont
96 cont:                                             ; preds = %for.body
97   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
98   %cond = load volatile i1, ptr %c
99   br i1 %cond, label %for.body, label %for.cond.cleanup
102 define void @f_sadd_3(ptr %a, ptr %c) {
103 ; CHECK-LABEL: Classifying expressions for: @f_sadd_3
104 entry:
105   br label %for.body
107 for.cond.cleanup:                                 ; preds = %cont
108   ret void
110 for.body:                                         ; preds = %entry, %cont
111 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
112 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body>
114   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
115   %idxprom = sext i32 %i.04 to i64
116   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
117   store i8 0, ptr %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 !{}
123 trap:                                             ; preds = %for.body
124   tail call void @llvm.trap() #2, !nosanitize !{}
125   unreachable, !nosanitize !{}
128 define void @f_sadd_4(ptr %a, ptr %c) {
129 ; CHECK-LABEL: Classifying expressions for: @f_sadd_4
130 entry:
131   br label %for.body
133 for.cond.cleanup:                                 ; preds = %cont
134   ret void
136 for.body:                                         ; preds = %entry, %cont
137 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
138 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body>
140   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
141   %idxprom = sext i32 %i.04 to i64
142   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
143   store i8 0, ptr %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
149 notrap:
150   br label %merge
152 merge:
153   %tmp3 = extractvalue { i32, i1 } %tmp0, 1
154   br i1 %tmp3, label %trap, label %for.body, !nosanitize !{}
156 trap:                                             ; preds = %for.body
157   tail call void @llvm.trap() #2, !nosanitize !{}
158   unreachable, !nosanitize !{}
161 define void @f_sadd_may_overflow(ptr %a, ptr %c) {
162 ; CHECK-LABEL: Classifying expressions for: @f_sadd_may_overflow
163 entry:
164   br label %for.body
166 for.cond.cleanup:                                 ; preds = %cont
167   ret void
169 for.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
173   %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
174   %idxprom = sext i32 %i.04 to i64
175   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
176   store i8 0, ptr %arrayidx, align 1
177   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
178   %cond1 = load volatile i1, ptr %c
179   br i1 %cond1, label %trap, label %cont, !nosanitize !{}
181 trap:                                             ; preds = %for.body
182   tail call void @llvm.trap() #2, !nosanitize !{}
183   unreachable, !nosanitize !{}
185 cont:                                             ; preds = %for.body
186   %tmp1 = extractvalue { i32, i1 } %tmp0, 0
187   %cond = load volatile i1, ptr %c
188   br i1 %cond, label %for.body, label %for.cond.cleanup
191 define void @f_uadd(ptr %a) {
192 ; CHECK-LABEL: Classifying expressions for: @f_uadd
193 entry:
194   br label %for.body
196 for.cond.cleanup:                                 ; preds = %cont
197   ret void
199 for.body:                                         ; preds = %entry, %cont
200 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
201 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body> U: [0,16) S: [0,16)
203   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
204   %idxprom = sext i32 %i.04 to i64
205   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
206   store i8 0, ptr %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 !{}
211 trap:                                             ; preds = %for.body
212   tail call void @llvm.trap(), !nosanitize !{}
213   unreachable, !nosanitize !{}
215 cont:                                             ; 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: constant max backedge-taken count is 15
222 define void @f_ssub(ptr nocapture %a) {
223 ; CHECK-LABEL: Classifying expressions for: @f_ssub
224 entry:
225   br label %for.body
227 for.cond.cleanup:                                 ; preds = %cont
228   ret void
230 for.body:                                         ; preds = %entry, %cont
231 ; CHECK:  %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
232 ; CHECK-NEXT:  -->  {15,+,-1}<nsw><%for.body> U: [0,16) S: [0,16)
234   %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
235   %idxprom = sext i32 %i.04 to i64
236   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
237   store i8 0, ptr %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 !{}
242 trap:                                             ; preds = %for.body
243   tail call void @llvm.trap(), !nosanitize !{}
244   unreachable, !nosanitize !{}
246 cont:                                             ; 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: constant max backedge-taken count is 15
253 define void @f_usub(ptr nocapture %a) {
254 ; CHECK-LABEL: Classifying expressions for: @f_usub
255 entry:
256   br label %for.body
258 for.cond.cleanup:                                 ; preds = %cont
259   ret void
261 for.body:                                         ; preds = %entry, %cont
262 ; CHECK:  %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
263 ; CHECK-NEXT:  -->  {15,+,-1}<nsw><%for.body> U: [0,16) S: [0,16)
265   %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
266   %idxprom = sext i32 %i.04 to i64
267   %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
268   store i8 0, ptr %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 !{}
273 trap:                                             ; preds = %for.body
274   tail call void @llvm.trap(), !nosanitize !{}
275   unreachable, !nosanitize !{}
277 cont:                                             ; 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: constant max backedge-taken count is 15
284 define 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
293 define 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
302 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
303 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
304 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
305 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
306 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
307 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
309 declare void @llvm.trap() #2