[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / overflows.ll
blob5122f98f4c82fdf96b40099fb61ed28fcdd6d3dc
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=correlated-propagation < %s | FileCheck %s
4 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
6 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
8 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
10 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
12 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
14 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
16 declare { i8, i1 } @llvm.umul.with.overflow.i8(i8, i8)
18 declare { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32>, <2 x i32>)
20 declare i8 @llvm.uadd.sat.i8(i8, i8)
21 declare i8 @llvm.sadd.sat.i8(i8, i8)
22 declare i8 @llvm.usub.sat.i8(i8, i8)
23 declare i8 @llvm.ssub.sat.i8(i8, i8)
24 declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>)
26 declare void @llvm.trap()
29 define i32 @signed_add(i32 %x, i32 %y) {
30 ; CHECK-LABEL: @signed_add(
31 ; CHECK-NEXT:  entry:
32 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[Y:%.*]], 0
33 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_LHS_FALSE:%.*]]
34 ; CHECK:       land.lhs.true:
35 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw nsw i32 2147483647, [[Y]]
36 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
37 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
38 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
39 ; CHECK:       trap:
40 ; CHECK-NEXT:    tail call void @llvm.trap()
41 ; CHECK-NEXT:    unreachable
42 ; CHECK:       cont:
43 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
44 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[TMP3]], [[X:%.*]]
45 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
46 ; CHECK:       lor.lhs.false:
47 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[Y]], 0
48 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LAND_LHS_TRUE3:%.*]], label [[COND_FALSE]]
49 ; CHECK:       land.lhs.true3:
50 ; CHECK-NEXT:    [[TMP4:%.*]] = sub nsw i32 -2147483648, [[Y]]
51 ; CHECK-NEXT:    [[TMP5:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP4]], 0
52 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
53 ; CHECK-NEXT:    br i1 [[TMP6]], label [[TRAP]], label [[CONT4:%.*]]
54 ; CHECK:       cont4:
55 ; CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
56 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[TMP7]], [[X]]
57 ; CHECK-NEXT:    br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
58 ; CHECK:       cond.false:
59 ; CHECK-NEXT:    [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
60 ; CHECK-NEXT:    [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0
61 ; CHECK-NEXT:    [[TMP10:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
62 ; CHECK-NEXT:    br i1 [[TMP10]], label [[TRAP]], label [[COND_END]]
63 ; CHECK:       cond.end:
64 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP9]], [[COND_FALSE]] ]
65 ; CHECK-NEXT:    ret i32 [[COND]]
67 entry:
68   %cmp = icmp sgt i32 %y, 0
69   br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
71 land.lhs.true:                                    ; preds = %entry
72   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 2147483647, i32 %y)
73   %1 = extractvalue { i32, i1 } %0, 1
74   br i1 %1, label %trap, label %cont
76 trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
77   tail call void @llvm.trap()
78   unreachable
80 cont:                                             ; preds = %land.lhs.true
81   %2 = extractvalue { i32, i1 } %0, 0
82   %cmp1 = icmp slt i32 %2, %x
83   br i1 %cmp1, label %cond.end, label %cond.false
85 lor.lhs.false:                                    ; preds = %entry
86   %cmp2 = icmp slt i32 %y, 0
87   br i1 %cmp2, label %land.lhs.true3, label %cond.false
89 land.lhs.true3:                                   ; preds = %lor.lhs.false
90   %3 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 -2147483648, i32 %y)
91   %4 = extractvalue { i32, i1 } %3, 1
92   br i1 %4, label %trap, label %cont4
94 cont4:                                            ; preds = %land.lhs.true3
95   %5 = extractvalue { i32, i1 } %3, 0
96   %cmp5 = icmp sgt i32 %5, %x
97   br i1 %cmp5, label %cond.end, label %cond.false
99 cond.false:                                       ; preds = %cont, %cont4, %lor.lhs.false
100   %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
101   %7 = extractvalue { i32, i1 } %6, 0
102   %8 = extractvalue { i32, i1 } %6, 1
103   br i1 %8, label %trap, label %cond.end
105 cond.end:                                         ; preds = %cond.false, %cont, %cont4
106   %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
107   ret i32 %cond
110 define i32 @unsigned_add(i32 %x, i32 %y) {
111 ; CHECK-LABEL: @unsigned_add(
112 ; CHECK-NEXT:  entry:
113 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw nsw i32 -1, [[Y:%.*]]
114 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
115 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
116 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
117 ; CHECK:       trap:
118 ; CHECK-NEXT:    tail call void @llvm.trap()
119 ; CHECK-NEXT:    unreachable
120 ; CHECK:       cont:
121 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
122 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[TMP3]], [[X:%.*]]
123 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
124 ; CHECK:       cond.false:
125 ; CHECK-NEXT:    [[TMP4:%.*]] = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
126 ; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
127 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
128 ; CHECK-NEXT:    br i1 [[TMP6]], label [[TRAP]], label [[COND_END]]
129 ; CHECK:       cond.end:
130 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT]] ], [ [[TMP5]], [[COND_FALSE]] ]
131 ; CHECK-NEXT:    ret i32 [[COND]]
133 entry:
134   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y)
135   %1 = extractvalue { i32, i1 } %0, 1
136   br i1 %1, label %trap, label %cont
138 trap:                                             ; preds = %cond.false, %entry
139   tail call void @llvm.trap()
140   unreachable
142 cont:                                             ; preds = %entry
143   %2 = extractvalue { i32, i1 } %0, 0
144   %cmp1 = icmp ult i32 %2, %x
145   br i1 %cmp1, label %cond.end, label %cond.false
147 cond.false:                                       ; preds = %cont
148   %3 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
149   %4 = extractvalue { i32, i1 } %3, 0
150   %5 = extractvalue { i32, i1 } %3, 1
151   br i1 %5, label %trap, label %cond.end
153 cond.end:                                         ; preds = %cond.false, %cont
154   %cond = phi i32 [ 0, %cont ], [ %4, %cond.false ]
155   ret i32 %cond
158 define i32 @signed_sub(i32 %x, i32 %y) {
159 ; CHECK-LABEL: @signed_sub(
160 ; CHECK-NEXT:  entry:
161 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[Y:%.*]], 0
162 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_LHS_FALSE:%.*]]
163 ; CHECK:       land.lhs.true:
164 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[Y]], 2147483647
165 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
166 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
167 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
168 ; CHECK:       trap:
169 ; CHECK-NEXT:    tail call void @llvm.trap()
170 ; CHECK-NEXT:    unreachable
171 ; CHECK:       cont:
172 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
173 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[TMP3]], [[X:%.*]]
174 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
175 ; CHECK:       lor.lhs.false:
176 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
177 ; CHECK-NEXT:    br i1 [[CMP2]], label [[COND_FALSE]], label [[LAND_LHS_TRUE3:%.*]]
178 ; CHECK:       land.lhs.true3:
179 ; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i32 [[Y]], -2147483648
180 ; CHECK-NEXT:    [[TMP5:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP4]], 0
181 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
182 ; CHECK-NEXT:    br i1 [[TMP6]], label [[TRAP]], label [[CONT4:%.*]]
183 ; CHECK:       cont4:
184 ; CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
185 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[TMP7]], [[X]]
186 ; CHECK-NEXT:    br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
187 ; CHECK:       cond.false:
188 ; CHECK-NEXT:    [[TMP8:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[X]], i32 [[Y]])
189 ; CHECK-NEXT:    [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0
190 ; CHECK-NEXT:    [[TMP10:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
191 ; CHECK-NEXT:    br i1 [[TMP10]], label [[TRAP]], label [[COND_END]]
192 ; CHECK:       cond.end:
193 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP9]], [[COND_FALSE]] ]
194 ; CHECK-NEXT:    ret i32 [[COND]]
196 entry:
197   %cmp = icmp slt i32 %y, 0
198   br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
200 land.lhs.true:                                    ; preds = %entry
201   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 2147483647)
202   %1 = extractvalue { i32, i1 } %0, 1
203   br i1 %1, label %trap, label %cont
205 trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
206   tail call void @llvm.trap()
207   unreachable
209 cont:                                             ; preds = %land.lhs.true
210   %2 = extractvalue { i32, i1 } %0, 0
211   %cmp1 = icmp slt i32 %2, %x
212   br i1 %cmp1, label %cond.end, label %cond.false
214 lor.lhs.false:                                    ; preds = %entry
215   %cmp2 = icmp eq i32 %y, 0
216   br i1 %cmp2, label %cond.false, label %land.lhs.true3
218 land.lhs.true3:                                   ; preds = %lor.lhs.false
219   %3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 -2147483648)
220   %4 = extractvalue { i32, i1 } %3, 1
221   br i1 %4, label %trap, label %cont4
223 cont4:                                            ; preds = %land.lhs.true3
224   %5 = extractvalue { i32, i1 } %3, 0
225   %cmp5 = icmp sgt i32 %5, %x
226   br i1 %cmp5, label %cond.end, label %cond.false
228 cond.false:                                       ; preds = %lor.lhs.false, %cont, %cont4
229   %6 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
230   %7 = extractvalue { i32, i1 } %6, 0
231   %8 = extractvalue { i32, i1 } %6, 1
232   br i1 %8, label %trap, label %cond.end
234 cond.end:                                         ; preds = %cond.false, %cont, %cont4
235   %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
236   ret i32 %cond
239 define i32 @unsigned_sub(i32 %x, i32 %y) {
240 ; CHECK-LABEL: @unsigned_sub(
241 ; CHECK-NEXT:  entry:
242 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
243 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
244 ; CHECK:       cond.false:
245 ; CHECK-NEXT:    [[TMP0:%.*]] = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X]], i32 [[Y]])
246 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
247 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
248 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[COND_END]]
249 ; CHECK:       trap:
250 ; CHECK-NEXT:    tail call void @llvm.trap()
251 ; CHECK-NEXT:    unreachable
252 ; CHECK:       cond.end:
253 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1]], [[COND_FALSE]] ]
254 ; CHECK-NEXT:    ret i32 [[COND]]
256 entry:
257   %cmp = icmp ult i32 %x, %y
258   br i1 %cmp, label %cond.end, label %cond.false
260 cond.false:                                       ; preds = %entry
261   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
262   %1 = extractvalue { i32, i1 } %0, 0
263   %2 = extractvalue { i32, i1 } %0, 1
264   br i1 %2, label %trap, label %cond.end
266 trap:                                             ; preds = %cond.false
267   tail call void @llvm.trap()
268   unreachable
270 cond.end:                                         ; preds = %cond.false, %entry
271   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
272   ret i32 %cond
275 define i32 @signed_add_r1(i32 %x) {
276 ; CHECK-LABEL: @signed_add_r1(
277 ; CHECK-NEXT:  entry:
278 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
279 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
280 ; CHECK:       cond.false:
281 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[X]], 1
282 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
283 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
284 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
285 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
286 ; CHECK:       trap:
287 ; CHECK-NEXT:    tail call void @llvm.trap()
288 ; CHECK-NEXT:    unreachable
289 ; CHECK:       cond.end:
290 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
291 ; CHECK-NEXT:    ret i32 [[COND]]
293 entry:
294   %cmp = icmp eq i32 %x, 2147483647
295   br i1 %cmp, label %cond.end, label %cond.false
297 cond.false:                                       ; preds = %entry
298   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
299   %1 = extractvalue { i32, i1 } %0, 0
300   %2 = extractvalue { i32, i1 } %0, 1
301   br i1 %2, label %trap, label %cond.end
303 trap:                                             ; preds = %cond.false
304   tail call void @llvm.trap()
305   unreachable
307 cond.end:                                         ; preds = %cond.false, %entry
308   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
309   ret i32 %cond
312 define i32 @unsigned_add_r1(i32 %x) {
313 ; CHECK-LABEL: @unsigned_add_r1(
314 ; CHECK-NEXT:  entry:
315 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -1
316 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
317 ; CHECK:       cond.false:
318 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[X]], 1
319 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
320 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
321 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
322 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
323 ; CHECK:       trap:
324 ; CHECK-NEXT:    tail call void @llvm.trap()
325 ; CHECK-NEXT:    unreachable
326 ; CHECK:       cond.end:
327 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
328 ; CHECK-NEXT:    ret i32 [[COND]]
330 entry:
331   %cmp = icmp eq i32 %x, -1
332   br i1 %cmp, label %cond.end, label %cond.false
334 cond.false:                                       ; preds = %entry
335   %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 1)
336   %1 = extractvalue { i32, i1 } %0, 0
337   %2 = extractvalue { i32, i1 } %0, 1
338   br i1 %2, label %trap, label %cond.end
340 trap:                                             ; preds = %cond.false
341   tail call void @llvm.trap()
342   unreachable
344 cond.end:                                         ; preds = %cond.false, %entry
345   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
346   ret i32 %cond
349 define i32 @signed_sub_r1(i32 %x) {
350 ; CHECK-LABEL: @signed_sub_r1(
351 ; CHECK-NEXT:  entry:
352 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
353 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
354 ; CHECK:       cond.false:
355 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nsw i32 [[X]], 1
356 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
357 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
358 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
359 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
360 ; CHECK:       trap:
361 ; CHECK-NEXT:    tail call void @llvm.trap()
362 ; CHECK-NEXT:    unreachable
363 ; CHECK:       cond.end:
364 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
365 ; CHECK-NEXT:    ret i32 [[COND]]
367 entry:
368   %cmp = icmp eq i32 %x, -2147483648
369   br i1 %cmp, label %cond.end, label %cond.false
371 cond.false:                                       ; preds = %entry
372   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 1)
373   %1 = extractvalue { i32, i1 } %0, 0
374   %2 = extractvalue { i32, i1 } %0, 1
375   br i1 %2, label %trap, label %cond.end
377 trap:                                             ; preds = %cond.false
378   tail call void @llvm.trap()
379   unreachable
381 cond.end:                                         ; preds = %cond.false, %entry
382   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
383   ret i32 %cond
386 define i32 @unsigned_sub_r1(i32 %x) {
387 ; CHECK-LABEL: @unsigned_sub_r1(
388 ; CHECK-NEXT:  entry:
389 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
390 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
391 ; CHECK:       cond.false:
392 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw i32 [[X]], 1
393 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
394 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
395 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
396 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
397 ; CHECK:       trap:
398 ; CHECK-NEXT:    tail call void @llvm.trap()
399 ; CHECK-NEXT:    unreachable
400 ; CHECK:       cond.end:
401 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
402 ; CHECK-NEXT:    ret i32 [[COND]]
404 entry:
405   %cmp = icmp eq i32 %x, 0
406   br i1 %cmp, label %cond.end, label %cond.false
408 cond.false:                                       ; preds = %entry
409   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 1)
410   %1 = extractvalue { i32, i1 } %0, 0
411   %2 = extractvalue { i32, i1 } %0, 1
412   br i1 %2, label %trap, label %cond.end
414 trap:                                             ; preds = %cond.false
415   tail call void @llvm.trap()
416   unreachable
418 cond.end:                                         ; preds = %cond.false, %entry
419   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
420   ret i32 %cond
423 define i32 @signed_add_rn1(i32 %x) {
424 ; CHECK-LABEL: @signed_add_rn1(
425 ; CHECK-NEXT:  entry:
426 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
427 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
428 ; CHECK:       cond.false:
429 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[X]], -1
430 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
431 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
432 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
433 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
434 ; CHECK:       trap:
435 ; CHECK-NEXT:    tail call void @llvm.trap()
436 ; CHECK-NEXT:    unreachable
437 ; CHECK:       cond.end:
438 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
439 ; CHECK-NEXT:    ret i32 [[COND]]
441 entry:
442   %cmp = icmp eq i32 %x, -2147483648
443   br i1 %cmp, label %cond.end, label %cond.false
445 cond.false:                                       ; preds = %entry
446   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 -1)
447   %1 = extractvalue { i32, i1 } %0, 0
448   %2 = extractvalue { i32, i1 } %0, 1
449   br i1 %2, label %trap, label %cond.end
451 trap:                                             ; preds = %cond.false
452   tail call void @llvm.trap()
453   unreachable
455 cond.end:                                         ; preds = %cond.false, %entry
456   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
457   ret i32 %cond
460 define i32 @signed_sub_rn1(i32 %x) {
461 ; CHECK-LABEL: @signed_sub_rn1(
462 ; CHECK-NEXT:  entry:
463 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
464 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
465 ; CHECK:       cond.false:
466 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nsw i32 [[X]], -1
467 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
468 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
469 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
470 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
471 ; CHECK:       trap:
472 ; CHECK-NEXT:    tail call void @llvm.trap()
473 ; CHECK-NEXT:    unreachable
474 ; CHECK:       cond.end:
475 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
476 ; CHECK-NEXT:    ret i32 [[COND]]
478 entry:
479   %cmp = icmp eq i32 %x, 2147483647
480   br i1 %cmp, label %cond.end, label %cond.false
482 cond.false:                                       ; preds = %entry
483   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 -1)
484   %1 = extractvalue { i32, i1 } %0, 0
485   %2 = extractvalue { i32, i1 } %0, 1
486   br i1 %2, label %trap, label %cond.end
488 trap:                                             ; preds = %cond.false
489   tail call void @llvm.trap()
490   unreachable
492 cond.end:                                         ; preds = %cond.false, %entry
493   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
494   ret i32 %cond
497 define i32 @unsigned_mul(i32 %x) {
498 ; CHECK-LABEL: @unsigned_mul(
499 ; CHECK-NEXT:  entry:
500 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 10000
501 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
502 ; CHECK:       cond.false:
503 ; CHECK-NEXT:    [[MULO1:%.*]] = mul nuw nsw i32 [[X]], 100
504 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[MULO1]], 0
505 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
506 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
507 ; CHECK-NEXT:    br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
508 ; CHECK:       trap:
509 ; CHECK-NEXT:    tail call void @llvm.trap()
510 ; CHECK-NEXT:    unreachable
511 ; CHECK:       cond.end:
512 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[COND_FALSE]] ]
513 ; CHECK-NEXT:    ret i32 [[COND]]
515 entry:
516   %cmp = icmp ugt i32 %x, 10000
517   br i1 %cmp, label %cond.end, label %cond.false
519 cond.false:                                       ; preds = %entry
520   %mulo = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 100)
521   %res = extractvalue { i32, i1 } %mulo, 0
522   %ov = extractvalue { i32, i1 } %mulo, 1
523   br i1 %ov, label %trap, label %cond.end
525 trap:                                             ; preds = %cond.false
526   tail call void @llvm.trap()
527   unreachable
529 cond.end:                                         ; preds = %cond.false, %entry
530   %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
531   ret i32 %cond
534 define i32 @signed_mul(i32 %x) {
535 ; CHECK-LABEL: @signed_mul(
536 ; CHECK-NEXT:  entry:
537 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[X:%.*]], 10000
538 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], -10000
539 ; CHECK-NEXT:    [[CMP3:%.*]] = or i1 [[CMP1]], [[CMP2]]
540 ; CHECK-NEXT:    br i1 [[CMP3]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
541 ; CHECK:       cond.false:
542 ; CHECK-NEXT:    [[MULO1:%.*]] = mul nsw i32 [[X]], 100
543 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[MULO1]], 0
544 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
545 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
546 ; CHECK-NEXT:    br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
547 ; CHECK:       trap:
548 ; CHECK-NEXT:    tail call void @llvm.trap()
549 ; CHECK-NEXT:    unreachable
550 ; CHECK:       cond.end:
551 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[COND_FALSE]] ]
552 ; CHECK-NEXT:    ret i32 [[COND]]
554 entry:
555   %cmp1 = icmp sgt i32 %x, 10000
556   %cmp2 = icmp slt i32 %x, -10000
557   %cmp3 = or i1 %cmp1, %cmp2
558   br i1 %cmp3, label %cond.end, label %cond.false
560 cond.false:                                       ; preds = %entry
561   %mulo = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 100)
562   %res = extractvalue { i32, i1 } %mulo, 0
563   %ov = extractvalue { i32, i1 } %mulo, 1
564   br i1 %ov, label %trap, label %cond.end
566 trap:                                             ; preds = %cond.false
567   tail call void @llvm.trap()
568   unreachable
570 cond.end:                                         ; preds = %cond.false, %entry
571   %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
572   ret i32 %cond
575 declare i32 @bar(i32)
577 define void @unsigned_loop(i32 %i) {
578 ; CHECK-LABEL: @unsigned_loop(
579 ; CHECK-NEXT:  entry:
580 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[I:%.*]], 0
581 ; CHECK-NEXT:    br i1 [[CMP3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
582 ; CHECK:       while.body.preheader:
583 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
584 ; CHECK:       while.body:
585 ; CHECK-NEXT:    [[I_ADDR_04:%.*]] = phi i32 [ [[TMP3:%.*]], [[CONT:%.*]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
586 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @bar(i32 [[I_ADDR_04]])
587 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw i32 [[I_ADDR_04]], 1
588 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
589 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
590 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT]]
591 ; CHECK:       trap:
592 ; CHECK-NEXT:    tail call void @llvm.trap()
593 ; CHECK-NEXT:    unreachable
594 ; CHECK:       cont:
595 ; CHECK-NEXT:    [[TMP3]] = extractvalue { i32, i1 } [[TMP1]], 0
596 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP3]], 0
597 ; CHECK-NEXT:    br i1 [[CMP]], label [[WHILE_END]], label [[WHILE_BODY]]
598 ; CHECK:       while.end:
599 ; CHECK-NEXT:    ret void
601 entry:
602   %cmp3 = icmp eq i32 %i, 0
603   br i1 %cmp3, label %while.end, label %while.body.preheader
605 while.body.preheader:                             ; preds = %entry
606   br label %while.body
608 while.body:                                       ; preds = %while.body.preheader, %cont
609   %i.addr.04 = phi i32 [ %2, %cont ], [ %i, %while.body.preheader ]
610   %call = tail call i32 @bar(i32 %i.addr.04)
611   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.addr.04, i32 1)
612   %1 = extractvalue { i32, i1 } %0, 1
613   br i1 %1, label %trap, label %cont
615 trap:                                             ; preds = %while.body
616   tail call void @llvm.trap()
617   unreachable
619 cont:                                             ; preds = %while.body
620   %2 = extractvalue { i32, i1 } %0, 0
621   %cmp = icmp eq i32 %2, 0
622   br i1 %cmp, label %while.end, label %while.body
624 while.end:                                        ; preds = %cont, %entry
625   ret void
628 define void @intrinsic_into_phi(i32 %n) {
629 ; CHECK-LABEL: @intrinsic_into_phi(
630 ; CHECK-NEXT:  entry:
631 ; CHECK-NEXT:    br label [[CONT:%.*]]
632 ; CHECK:       for.cond:
633 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[DOTLCSSA:%.*]], 1
634 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[TMP0]], 0
635 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
636 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT]]
637 ; CHECK:       trap:
638 ; CHECK-NEXT:    tail call void @llvm.trap()
639 ; CHECK-NEXT:    unreachable
640 ; CHECK:       cont:
641 ; CHECK-NEXT:    [[TMP3:%.*]] = phi { i32, i1 } [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP1]], [[FOR_COND:%.*]] ]
642 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0
643 ; CHECK-NEXT:    [[CALL9:%.*]] = tail call i32 @bar(i32 [[TMP4]])
644 ; CHECK-NEXT:    [[TOBOOL10:%.*]] = icmp eq i32 [[CALL9]], 0
645 ; CHECK-NEXT:    br i1 [[TOBOOL10]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
646 ; CHECK:       while.body.preheader:
647 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
648 ; CHECK:       while.cond:
649 ; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP7:%.*]], 0
650 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @bar(i32 [[TMP5]])
651 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[CALL]], 0
652 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END]], label [[WHILE_BODY]]
653 ; CHECK:       while.body:
654 ; CHECK-NEXT:    [[TMP6:%.*]] = phi i32 [ [[TMP5]], [[WHILE_COND:%.*]] ], [ [[TMP4]], [[WHILE_BODY_PREHEADER]] ]
655 ; CHECK-NEXT:    [[TMP7]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP6]], i32 1)
656 ; CHECK-NEXT:    [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
657 ; CHECK-NEXT:    br i1 [[TMP8]], label [[TRAP]], label [[WHILE_COND]]
658 ; CHECK:       while.end:
659 ; CHECK-NEXT:    [[DOTLCSSA]] = phi i32 [ [[TMP4]], [[CONT]] ], [ [[TMP5]], [[WHILE_COND]] ]
660 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[DOTLCSSA]], [[N:%.*]]
661 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND]], label [[CLEANUP2:%.*]]
662 ; CHECK:       cleanup2:
663 ; CHECK-NEXT:    ret void
665 entry:
666   br label %cont
668 for.cond:                                         ; preds = %while.end
669   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %.lcssa, i32 1)
670   %1 = extractvalue { i32, i1 } %0, 1
671   br i1 %1, label %trap, label %cont
673 trap:                                             ; preds = %for.cond, %while.body
674   tail call void @llvm.trap()
675   unreachable
677 cont:                                             ; preds = %entry, %for.cond
678   %2 = phi { i32, i1 } [ zeroinitializer, %entry ], [ %0, %for.cond ]
679   %3 = extractvalue { i32, i1 } %2, 0
680   %call9 = tail call i32 @bar(i32 %3)
681   %tobool10 = icmp eq i32 %call9, 0
682   br i1 %tobool10, label %while.end, label %while.body.preheader
684 while.body.preheader:                             ; preds = %cont
685   br label %while.body
687 while.cond:                                       ; preds = %while.body
688   %4 = extractvalue { i32, i1 } %6, 0
689   %call = tail call i32 @bar(i32 %4)
690   %tobool = icmp eq i32 %call, 0
691   br i1 %tobool, label %while.end, label %while.body
693 while.body:                                       ; preds = %while.body.preheader, %while.cond
694   %5 = phi i32 [ %4, %while.cond ], [ %3, %while.body.preheader ]
695   %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %5, i32 1)
696   %7 = extractvalue { i32, i1 } %6, 1
697   br i1 %7, label %trap, label %while.cond
699 while.end:                                        ; preds = %while.cond, %cont
700   %.lcssa = phi i32 [ %3, %cont ], [ %4, %while.cond ]
701   %cmp = icmp slt i32 %.lcssa, %n
702   br i1 %cmp, label %for.cond, label %cleanup2
704 cleanup2:                                         ; preds = %while.end
705   ret void
708 define { i8, i1 } @signed_mul_constant_folding() {
709 ; CHECK-LABEL: @signed_mul_constant_folding(
710 ; CHECK-NEXT:    ret { i8, i1 } { i8 2, i1 false }
712   %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 1, i8 2)
713   ret { i8, i1 } %mul
716 define { <2 x i32>, <2 x i1> } @uaddo_vec(<2 x i32> %a) {
717 ; CHECK-LABEL: @uaddo_vec(
718 ; CHECK-NEXT:    [[ADD:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[A:%.*]], <2 x i32> splat (i32 1))
719 ; CHECK-NEXT:    ret { <2 x i32>, <2 x i1> } [[ADD]]
721   %add = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> %a, <2 x i32> <i32 1, i32 1>)
722   ret { <2 x i32>, <2 x i1> } %add
726 define i8 @uadd_sat_no_unsigned_overflow(i8 %x) {
727 ; CHECK-LABEL: @uadd_sat_no_unsigned_overflow(
728 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 100
729 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
730 ; CHECK:       trap:
731 ; CHECK-NEXT:    call void @llvm.trap()
732 ; CHECK-NEXT:    unreachable
733 ; CHECK:       cont:
734 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw i8 [[X]], 100
735 ; CHECK-NEXT:    ret i8 [[RES1]]
737   %cmp = icmp ugt i8 %x, 100
738   br i1 %cmp, label %trap, label %cont
740 trap:
741   call void @llvm.trap()
742   unreachable
744 cont:
745   %res = call i8 @llvm.uadd.sat.i8(i8 %x, i8 100)
746   ret i8 %res
749 define i8 @uadd_sat_no_overflow(i8 %x) {
750 ; CHECK-LABEL: @uadd_sat_no_overflow(
751 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 27
752 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
753 ; CHECK:       trap:
754 ; CHECK-NEXT:    call void @llvm.trap()
755 ; CHECK-NEXT:    unreachable
756 ; CHECK:       cont:
757 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw i8 [[X]], 100
758 ; CHECK-NEXT:    ret i8 [[RES1]]
760   %cmp = icmp ugt i8 %x, 27
761   br i1 %cmp, label %trap, label %cont
763 trap:
764   call void @llvm.trap()
765   unreachable
767 cont:
768   %res = call i8 @llvm.uadd.sat.i8(i8 %x, i8 100)
769   ret i8 %res
772 define i8 @sadd_sat_no_signed_overflow(i8 %x) {
773 ; CHECK-LABEL: @sadd_sat_no_signed_overflow(
774 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 100
775 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
776 ; CHECK:       trap:
777 ; CHECK-NEXT:    call void @llvm.trap()
778 ; CHECK-NEXT:    unreachable
779 ; CHECK:       cont:
780 ; CHECK-NEXT:    [[RES1:%.*]] = add nsw i8 [[X]], 20
781 ; CHECK-NEXT:    ret i8 [[RES1]]
783   %cmp = icmp sgt i8 %x, 100
784   br i1 %cmp, label %trap, label %cont
786 trap:
787   call void @llvm.trap()
788   unreachable
790 cont:
791   %res = call i8 @llvm.sadd.sat.i8(i8 %x, i8 20)
792   ret i8 %res
795 define i8 @sadd_sat_no_overflow(i8 %x) {
796 ; CHECK-LABEL: @sadd_sat_no_overflow(
797 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 107
798 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
799 ; CHECK:       trap:
800 ; CHECK-NEXT:    call void @llvm.trap()
801 ; CHECK-NEXT:    unreachable
802 ; CHECK:       cont:
803 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw i8 [[X]], 20
804 ; CHECK-NEXT:    ret i8 [[RES1]]
806   %cmp = icmp ugt i8 %x, 107
807   br i1 %cmp, label %trap, label %cont
809 trap:
810   call void @llvm.trap()
811   unreachable
813 cont:
814   %res = call i8 @llvm.sadd.sat.i8(i8 %x, i8 20)
815   ret i8 %res
818 define i8 @usub_sat_no_unsigned_overflow(i8 %x) {
819 ; CHECK-LABEL: @usub_sat_no_unsigned_overflow(
820 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], 100
821 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
822 ; CHECK:       trap:
823 ; CHECK-NEXT:    call void @llvm.trap()
824 ; CHECK-NEXT:    unreachable
825 ; CHECK:       cont:
826 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw i8 [[X]], 100
827 ; CHECK-NEXT:    ret i8 [[RES1]]
829   %cmp = icmp ult i8 %x, 100
830   br i1 %cmp, label %trap, label %cont
832 trap:
833   call void @llvm.trap()
834   unreachable
836 cont:
837   %res = call i8 @llvm.usub.sat.i8(i8 %x, i8 100)
838   ret i8 %res
841 define i8 @usub_sat_no_overflow(i8 %x) {
842 ; CHECK-LABEL: @usub_sat_no_overflow(
843 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], -28
844 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
845 ; CHECK:       trap:
846 ; CHECK-NEXT:    call void @llvm.trap()
847 ; CHECK-NEXT:    unreachable
848 ; CHECK:       cont:
849 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i8 [[X]], 100
850 ; CHECK-NEXT:    ret i8 [[RES1]]
852   %cmp = icmp ult i8 %x, 228
853   br i1 %cmp, label %trap, label %cont
855 trap:
856   call void @llvm.trap()
857   unreachable
859 cont:
860   %res = call i8 @llvm.usub.sat.i8(i8 %x, i8 100)
861   ret i8 %res
864 define i8 @ssub_sat_no_signed_overflow(i8 %x) {
865 ; CHECK-LABEL: @ssub_sat_no_signed_overflow(
866 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -100
867 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
868 ; CHECK:       trap:
869 ; CHECK-NEXT:    call void @llvm.trap()
870 ; CHECK-NEXT:    unreachable
871 ; CHECK:       cont:
872 ; CHECK-NEXT:    [[RES1:%.*]] = sub nsw i8 [[X]], 20
873 ; CHECK-NEXT:    ret i8 [[RES1]]
875   %cmp = icmp slt i8 %x, -100
876   br i1 %cmp, label %trap, label %cont
878 trap:
879   call void @llvm.trap()
880   unreachable
882 cont:
883   %res = call i8 @llvm.ssub.sat.i8(i8 %x, i8 20)
884   ret i8 %res
887 define i8 @ssub_sat_no_overflow(i8 %x) {
888 ; CHECK-LABEL: @ssub_sat_no_overflow(
889 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], -108
890 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
891 ; CHECK:       trap:
892 ; CHECK-NEXT:    call void @llvm.trap()
893 ; CHECK-NEXT:    unreachable
894 ; CHECK:       cont:
895 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i8 [[X]], 20
896 ; CHECK-NEXT:    ret i8 [[RES1]]
898   %cmp = icmp ult i8 %x, 148
899   br i1 %cmp, label %trap, label %cont
901 trap:
902   call void @llvm.trap()
903   unreachable
905 cont:
906   %res = call i8 @llvm.ssub.sat.i8(i8 %x, i8 20)
907   ret i8 %res
910 define <2 x i8> @uadd_sat_vec(<2 x i8> %a) {
911 ; CHECK-LABEL: @uadd_sat_vec(
912 ; CHECK-NEXT:    [[ADD:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 1))
913 ; CHECK-NEXT:    ret <2 x i8> [[ADD]]
915   %add = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 1, i8 1>)
916   ret <2 x i8> %add
919 ; In the following tests, we should first simplify a with.overflow intrinsic
920 ; to a simple arithmetic operation and insertvalue, but also simplify the
921 ; subsequent comparison that is based on it.
923 define i1 @sadd_and_cmp(i32 %x, i32 %y) #0 {
924 ; CHECK-LABEL: @sadd_and_cmp(
925 ; CHECK-NEXT:  entry:
926 ; CHECK-NEXT:    [[X_OFFSET:%.*]] = add i32 [[X:%.*]], 9
927 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X_OFFSET]], 19
928 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
929 ; CHECK:       cont1:
930 ; CHECK-NEXT:    [[Y_OFFSET:%.*]] = add i32 [[Y:%.*]], 9
931 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y_OFFSET]], 19
932 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
933 ; CHECK:       cont2:
934 ; CHECK-NEXT:    [[RES1:%.*]] = add nsw i32 [[X]], [[Y]]
935 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[RES1]], 0
936 ; CHECK-NEXT:    [[ADD:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
937 ; CHECK-NEXT:    br label [[OUT]]
938 ; CHECK:       out:
939 ; CHECK-NEXT:    ret i1 true
941 entry:
942   %x.offset = add i32 %x, 9
943   %cmp1 = icmp ult i32 %x.offset, 19
944   br i1 %cmp1, label %cont1, label %out
946 cont1:
947   %y.offset = add i32 %y, 9
948   %cmp2 = icmp ult i32 %y.offset, 19
949   br i1 %cmp2, label %cont2, label %out
951 cont2:
952   ; x = [-9,10), y = [-9,10)
953   %res = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
954   %add = extractvalue { i32, i1 } %res, 0
955   ; add = [-18,19)
956   %cmp3 = icmp slt i32 %add, 19
957   br label %out
959 out:
960   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
961   ret i1 %ret
965 define i1 @uadd_and_cmp(i32 %x, i32 %y) #0 {
966 ; CHECK-LABEL: @uadd_and_cmp(
967 ; CHECK-NEXT:  entry:
968 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
969 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
970 ; CHECK:       cont1:
971 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
972 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
973 ; CHECK:       cont2:
974 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw i32 [[X]], [[Y]]
975 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[RES1]], 0
976 ; CHECK-NEXT:    [[ADD:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
977 ; CHECK-NEXT:    br label [[OUT]]
978 ; CHECK:       out:
979 ; CHECK-NEXT:    ret i1 true
981 entry:
982   %cmp1 = icmp ult i32 %x, 10
983   br i1 %cmp1, label %cont1, label %out
985 cont1:
986   %cmp2 = icmp ult i32 %y, 10
987   br i1 %cmp2, label %cont2, label %out
989 cont2:
990   %res = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
991   %add = extractvalue { i32, i1 } %res, 0
992   %cmp3 = icmp ult i32 %add, 19
993   br label %out
995 out:
996   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
997   ret i1 %ret
1000 define i1 @ssub_and_cmp(i32 %x, i32 %y) #0 {
1001 ; CHECK-LABEL: @ssub_and_cmp(
1002 ; CHECK-NEXT:  entry:
1003 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
1004 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1005 ; CHECK:       cont1:
1006 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
1007 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1008 ; CHECK:       cont2:
1009 ; CHECK-NEXT:    [[OFFSET:%.*]] = add nuw nsw i32 [[X]], 9
1010 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i32 [[OFFSET]], [[Y]]
1011 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[RES1]], 0
1012 ; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1013 ; CHECK-NEXT:    br label [[OUT]]
1014 ; CHECK:       out:
1015 ; CHECK-NEXT:    ret i1 true
1017 entry:
1018   %cmp1 = icmp ult i32 %x, 10
1019   br i1 %cmp1, label %cont1, label %out
1021 cont1:
1022   %cmp2 = icmp ult i32 %y, 10
1023   br i1 %cmp2, label %cont2, label %out
1025 cont2:
1026   %offset = add i32 %x, 9
1027   ; x = [0,10), y = [0,10), offset = [9,19)
1028   %res = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %offset, i32 %y)
1029   %sub = extractvalue { i32, i1 } %res, 0
1030   %cmp3 = icmp ult i32 %sub, 19
1031   br label %out
1033 out:
1034   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
1035   ret i1 %ret
1038 define i1 @usub_and_cmp(i32 %x, i32 %y) #0 {
1039 ; CHECK-LABEL: @usub_and_cmp(
1040 ; CHECK-NEXT:  entry:
1041 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
1042 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1043 ; CHECK:       cont1:
1044 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
1045 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1046 ; CHECK:       cont2:
1047 ; CHECK-NEXT:    [[OFFSET:%.*]] = add nuw nsw i32 [[X]], 9
1048 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i32 [[OFFSET]], [[Y]]
1049 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[RES1]], 0
1050 ; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1051 ; CHECK-NEXT:    br label [[OUT]]
1052 ; CHECK:       out:
1053 ; CHECK-NEXT:    ret i1 true
1055 entry:
1056   %cmp1 = icmp ult i32 %x, 10
1057   br i1 %cmp1, label %cont1, label %out
1059 cont1:
1060   %cmp2 = icmp ult i32 %y, 10
1061   br i1 %cmp2, label %cont2, label %out
1063 cont2:
1064   %offset = add i32 %x, 9
1065   ; x = [0,10), y = [0,10), offset = [9,19)
1066   %res = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %offset, i32 %y)
1067   %sub = extractvalue { i32, i1 } %res, 0
1068   %cmp3 = icmp ult i32 %sub, 19
1069   br label %out
1071 out:
1072   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
1073   ret i1 %ret
1076 define i1 @smul_and_cmp(i32 %x, i32 %y) #0 {
1077 ; CHECK-LABEL: @smul_and_cmp(
1078 ; CHECK-NEXT:  entry:
1079 ; CHECK-NEXT:    [[X_OFFSET:%.*]] = add i32 [[X:%.*]], 9
1080 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X_OFFSET]], 19
1081 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1082 ; CHECK:       cont1:
1083 ; CHECK-NEXT:    [[Y_OFFSET:%.*]] = add i32 [[Y:%.*]], 9
1084 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y_OFFSET]], 19
1085 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1086 ; CHECK:       cont2:
1087 ; CHECK-NEXT:    [[RES1:%.*]] = mul nsw i32 [[X]], [[Y]]
1088 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[RES1]], 0
1089 ; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1090 ; CHECK-NEXT:    br label [[OUT]]
1091 ; CHECK:       out:
1092 ; CHECK-NEXT:    ret i1 true
1094 entry:
1095   %x.offset = add i32 %x, 9
1096   %cmp1 = icmp ult i32 %x.offset, 19
1097   br i1 %cmp1, label %cont1, label %out
1099 cont1:
1100   %y.offset = add i32 %y, 9
1101   %cmp2 = icmp ult i32 %y.offset, 19
1102   br i1 %cmp2, label %cont2, label %out
1104 cont2:
1105   ; x = [-9,10), y = [-9,10)
1106   %res = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 %y)
1107   %mul = extractvalue { i32, i1 } %res, 0
1108   %cmp3 = icmp sle i32 %mul, 81
1109   %cmp4 = icmp sge i32 %mul, -81
1110   %cmp5 = and i1 %cmp3, %cmp4
1111   br label %out
1113 out:
1114   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp5, %cont2 ]
1115   ret i1 %ret
1118 define i1 @umul_and_cmp(i32 %x, i32 %y) #0 {
1119 ; CHECK-LABEL: @umul_and_cmp(
1120 ; CHECK-NEXT:  entry:
1121 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 100
1122 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1123 ; CHECK:       cont1:
1124 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 100
1125 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1126 ; CHECK:       cont2:
1127 ; CHECK-NEXT:    [[RES1:%.*]] = mul nuw nsw i32 [[X]], [[Y]]
1128 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[RES1]], 0
1129 ; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1130 ; CHECK-NEXT:    br label [[OUT]]
1131 ; CHECK:       out:
1132 ; CHECK-NEXT:    ret i1 true
1134 entry:
1135   %cmp1 = icmp ult i32 %x, 100
1136   br i1 %cmp1, label %cont1, label %out
1138 cont1:
1139   %cmp2 = icmp ult i32 %y, 100
1140   br i1 %cmp2, label %cont2, label %out
1142 cont2:
1143   %res = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
1144   %mul = extractvalue { i32, i1 } %res, 0
1145   %cmp3 = icmp ule i32 %mul, 9801
1146   br label %out
1148 out:
1149   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
1150   ret i1 %ret
1153 define i8 @uadd_sat_undef_range(i8 %x) {
1154 ; CHECK-LABEL: @uadd_sat_undef_range(
1155 ; CHECK-NEXT:  entry:
1156 ; CHECK-NEXT:    switch i8 [[X:%.*]], label [[JOIN:%.*]] [
1157 ; CHECK-NEXT:      i8 1, label [[CASE1:%.*]]
1158 ; CHECK-NEXT:      i8 2, label [[CASE2:%.*]]
1159 ; CHECK-NEXT:    ]
1160 ; CHECK:       case1:
1161 ; CHECK-NEXT:    br label [[JOIN]]
1162 ; CHECK:       case2:
1163 ; CHECK-NEXT:    br label [[JOIN]]
1164 ; CHECK:       join:
1165 ; CHECK-NEXT:    [[PHI:%.*]] = phi i8 [ 1, [[CASE1]] ], [ 2, [[CASE2]] ], [ undef, [[ENTRY:%.*]] ]
1166 ; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[PHI]], i8 100)
1167 ; CHECK-NEXT:    ret i8 [[RES]]
1169 entry:
1170   switch i8 %x, label %join [
1171   i8 1, label %case1
1172   i8 2, label %case2
1173   ]
1175 case1:
1176   br label %join
1178 case2:
1179   br label %join
1181 join:
1182   %phi = phi i8 [ 1, %case1 ], [ 2, %case2 ], [ undef, %entry ]
1183   %res = call i8 @llvm.uadd.sat.i8(i8 %phi, i8 100)
1184   ret i8 %res