[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / CorrelatedValuePropagation / overflows.ll
blob211e63aafde714e994b008c397c59d7756528aa5
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -correlated-propagation < %s | FileCheck %s
4 ; Check that debug locations are preserved. For more info see:
5 ;   https://llvm.org/docs/SourceLevelDebugging.html#fixing-errors
6 ; RUN: opt < %s -enable-debugify -correlated-propagation -S 2>&1 | \
7 ; RUN:   FileCheck %s -check-prefix=DEBUG
8 ; DEBUG: CheckModuleDebugify: PASS
10 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
12 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
14 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
16 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
18 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
20 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
22 declare { i8, i1 } @llvm.umul.with.overflow.i8(i8, i8)
24 declare { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32>, <2 x i32>)
26 declare i8 @llvm.uadd.sat.i8(i8, i8)
27 declare i8 @llvm.sadd.sat.i8(i8, i8)
28 declare i8 @llvm.usub.sat.i8(i8, i8)
29 declare i8 @llvm.ssub.sat.i8(i8, i8)
30 declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>)
32 declare void @llvm.trap()
35 define i32 @signed_add(i32 %x, i32 %y) {
36 ; CHECK-LABEL: @signed_add(
37 ; CHECK-NEXT:  entry:
38 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[Y:%.*]], 0
39 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_LHS_FALSE:%.*]]
40 ; CHECK:       land.lhs.true:
41 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw nsw i32 2147483647, [[Y]]
42 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
43 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
44 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
45 ; CHECK:       trap:
46 ; CHECK-NEXT:    tail call void @llvm.trap()
47 ; CHECK-NEXT:    unreachable
48 ; CHECK:       cont:
49 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
50 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[TMP3]], [[X:%.*]]
51 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
52 ; CHECK:       lor.lhs.false:
53 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[Y]], 0
54 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LAND_LHS_TRUE3:%.*]], label [[COND_FALSE]]
55 ; CHECK:       land.lhs.true3:
56 ; CHECK-NEXT:    [[TMP4:%.*]] = sub nsw i32 -2147483648, [[Y]]
57 ; CHECK-NEXT:    [[TMP5:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP4]], 0
58 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
59 ; CHECK-NEXT:    br i1 [[TMP6]], label [[TRAP]], label [[CONT4:%.*]]
60 ; CHECK:       cont4:
61 ; CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
62 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[TMP7]], [[X]]
63 ; CHECK-NEXT:    br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
64 ; CHECK:       cond.false:
65 ; CHECK-NEXT:    [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
66 ; CHECK-NEXT:    [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0
67 ; CHECK-NEXT:    [[TMP10:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
68 ; CHECK-NEXT:    br i1 [[TMP10]], label [[TRAP]], label [[COND_END]]
69 ; CHECK:       cond.end:
70 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP9]], [[COND_FALSE]] ]
71 ; CHECK-NEXT:    ret i32 [[COND]]
73 entry:
74   %cmp = icmp sgt i32 %y, 0
75   br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
77 land.lhs.true:                                    ; preds = %entry
78   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 2147483647, i32 %y)
79   %1 = extractvalue { i32, i1 } %0, 1
80   br i1 %1, label %trap, label %cont
82 trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
83   tail call void @llvm.trap()
84   unreachable
86 cont:                                             ; preds = %land.lhs.true
87   %2 = extractvalue { i32, i1 } %0, 0
88   %cmp1 = icmp slt i32 %2, %x
89   br i1 %cmp1, label %cond.end, label %cond.false
91 lor.lhs.false:                                    ; preds = %entry
92   %cmp2 = icmp slt i32 %y, 0
93   br i1 %cmp2, label %land.lhs.true3, label %cond.false
95 land.lhs.true3:                                   ; preds = %lor.lhs.false
96   %3 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 -2147483648, i32 %y)
97   %4 = extractvalue { i32, i1 } %3, 1
98   br i1 %4, label %trap, label %cont4
100 cont4:                                            ; preds = %land.lhs.true3
101   %5 = extractvalue { i32, i1 } %3, 0
102   %cmp5 = icmp sgt i32 %5, %x
103   br i1 %cmp5, label %cond.end, label %cond.false
105 cond.false:                                       ; preds = %cont, %cont4, %lor.lhs.false
106   %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
107   %7 = extractvalue { i32, i1 } %6, 0
108   %8 = extractvalue { i32, i1 } %6, 1
109   br i1 %8, label %trap, label %cond.end
111 cond.end:                                         ; preds = %cond.false, %cont, %cont4
112   %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
113   ret i32 %cond
116 define i32 @unsigned_add(i32 %x, i32 %y) {
117 ; CHECK-LABEL: @unsigned_add(
118 ; CHECK-NEXT:  entry:
119 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw nsw i32 -1, [[Y:%.*]]
120 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
121 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
122 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
123 ; CHECK:       trap:
124 ; CHECK-NEXT:    tail call void @llvm.trap()
125 ; CHECK-NEXT:    unreachable
126 ; CHECK:       cont:
127 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
128 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[TMP3]], [[X:%.*]]
129 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
130 ; CHECK:       cond.false:
131 ; CHECK-NEXT:    [[TMP4:%.*]] = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
132 ; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
133 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
134 ; CHECK-NEXT:    br i1 [[TMP6]], label [[TRAP]], label [[COND_END]]
135 ; CHECK:       cond.end:
136 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT]] ], [ [[TMP5]], [[COND_FALSE]] ]
137 ; CHECK-NEXT:    ret i32 [[COND]]
139 entry:
140   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y)
141   %1 = extractvalue { i32, i1 } %0, 1
142   br i1 %1, label %trap, label %cont
144 trap:                                             ; preds = %cond.false, %entry
145   tail call void @llvm.trap()
146   unreachable
148 cont:                                             ; preds = %entry
149   %2 = extractvalue { i32, i1 } %0, 0
150   %cmp1 = icmp ult i32 %2, %x
151   br i1 %cmp1, label %cond.end, label %cond.false
153 cond.false:                                       ; preds = %cont
154   %3 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
155   %4 = extractvalue { i32, i1 } %3, 0
156   %5 = extractvalue { i32, i1 } %3, 1
157   br i1 %5, label %trap, label %cond.end
159 cond.end:                                         ; preds = %cond.false, %cont
160   %cond = phi i32 [ 0, %cont ], [ %4, %cond.false ]
161   ret i32 %cond
164 define i32 @signed_sub(i32 %x, i32 %y) {
165 ; CHECK-LABEL: @signed_sub(
166 ; CHECK-NEXT:  entry:
167 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[Y:%.*]], 0
168 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_LHS_FALSE:%.*]]
169 ; CHECK:       land.lhs.true:
170 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[Y]], 2147483647
171 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
172 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
173 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
174 ; CHECK:       trap:
175 ; CHECK-NEXT:    tail call void @llvm.trap()
176 ; CHECK-NEXT:    unreachable
177 ; CHECK:       cont:
178 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
179 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[TMP3]], [[X:%.*]]
180 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
181 ; CHECK:       lor.lhs.false:
182 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
183 ; CHECK-NEXT:    br i1 [[CMP2]], label [[COND_FALSE]], label [[LAND_LHS_TRUE3:%.*]]
184 ; CHECK:       land.lhs.true3:
185 ; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i32 [[Y]], -2147483648
186 ; CHECK-NEXT:    [[TMP5:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP4]], 0
187 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
188 ; CHECK-NEXT:    br i1 [[TMP6]], label [[TRAP]], label [[CONT4:%.*]]
189 ; CHECK:       cont4:
190 ; CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
191 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[TMP7]], [[X]]
192 ; CHECK-NEXT:    br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
193 ; CHECK:       cond.false:
194 ; CHECK-NEXT:    [[TMP8:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[X]], i32 [[Y]])
195 ; CHECK-NEXT:    [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0
196 ; CHECK-NEXT:    [[TMP10:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
197 ; CHECK-NEXT:    br i1 [[TMP10]], label [[TRAP]], label [[COND_END]]
198 ; CHECK:       cond.end:
199 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP9]], [[COND_FALSE]] ]
200 ; CHECK-NEXT:    ret i32 [[COND]]
202 entry:
203   %cmp = icmp slt i32 %y, 0
204   br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
206 land.lhs.true:                                    ; preds = %entry
207   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 2147483647)
208   %1 = extractvalue { i32, i1 } %0, 1
209   br i1 %1, label %trap, label %cont
211 trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
212   tail call void @llvm.trap()
213   unreachable
215 cont:                                             ; preds = %land.lhs.true
216   %2 = extractvalue { i32, i1 } %0, 0
217   %cmp1 = icmp slt i32 %2, %x
218   br i1 %cmp1, label %cond.end, label %cond.false
220 lor.lhs.false:                                    ; preds = %entry
221   %cmp2 = icmp eq i32 %y, 0
222   br i1 %cmp2, label %cond.false, label %land.lhs.true3
224 land.lhs.true3:                                   ; preds = %lor.lhs.false
225   %3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 -2147483648)
226   %4 = extractvalue { i32, i1 } %3, 1
227   br i1 %4, label %trap, label %cont4
229 cont4:                                            ; preds = %land.lhs.true3
230   %5 = extractvalue { i32, i1 } %3, 0
231   %cmp5 = icmp sgt i32 %5, %x
232   br i1 %cmp5, label %cond.end, label %cond.false
234 cond.false:                                       ; preds = %lor.lhs.false, %cont, %cont4
235   %6 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
236   %7 = extractvalue { i32, i1 } %6, 0
237   %8 = extractvalue { i32, i1 } %6, 1
238   br i1 %8, label %trap, label %cond.end
240 cond.end:                                         ; preds = %cond.false, %cont, %cont4
241   %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
242   ret i32 %cond
245 define i32 @unsigned_sub(i32 %x, i32 %y) {
246 ; CHECK-LABEL: @unsigned_sub(
247 ; CHECK-NEXT:  entry:
248 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
249 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
250 ; CHECK:       cond.false:
251 ; CHECK-NEXT:    [[TMP0:%.*]] = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X]], i32 [[Y]])
252 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
253 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
254 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[COND_END]]
255 ; CHECK:       trap:
256 ; CHECK-NEXT:    tail call void @llvm.trap()
257 ; CHECK-NEXT:    unreachable
258 ; CHECK:       cond.end:
259 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1]], [[COND_FALSE]] ]
260 ; CHECK-NEXT:    ret i32 [[COND]]
262 entry:
263   %cmp = icmp ult i32 %x, %y
264   br i1 %cmp, label %cond.end, label %cond.false
266 cond.false:                                       ; preds = %entry
267   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
268   %1 = extractvalue { i32, i1 } %0, 0
269   %2 = extractvalue { i32, i1 } %0, 1
270   br i1 %2, label %trap, label %cond.end
272 trap:                                             ; preds = %cond.false
273   tail call void @llvm.trap()
274   unreachable
276 cond.end:                                         ; preds = %cond.false, %entry
277   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
278   ret i32 %cond
281 define i32 @signed_add_r1(i32 %x) {
282 ; CHECK-LABEL: @signed_add_r1(
283 ; CHECK-NEXT:  entry:
284 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
285 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
286 ; CHECK:       cond.false:
287 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[X]], 1
288 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
289 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
290 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
291 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
292 ; CHECK:       trap:
293 ; CHECK-NEXT:    tail call void @llvm.trap()
294 ; CHECK-NEXT:    unreachable
295 ; CHECK:       cond.end:
296 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
297 ; CHECK-NEXT:    ret i32 [[COND]]
299 entry:
300   %cmp = icmp eq i32 %x, 2147483647
301   br i1 %cmp, label %cond.end, label %cond.false
303 cond.false:                                       ; preds = %entry
304   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
305   %1 = extractvalue { i32, i1 } %0, 0
306   %2 = extractvalue { i32, i1 } %0, 1
307   br i1 %2, label %trap, label %cond.end
309 trap:                                             ; preds = %cond.false
310   tail call void @llvm.trap()
311   unreachable
313 cond.end:                                         ; preds = %cond.false, %entry
314   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
315   ret i32 %cond
318 define i32 @unsigned_add_r1(i32 %x) {
319 ; CHECK-LABEL: @unsigned_add_r1(
320 ; CHECK-NEXT:  entry:
321 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -1
322 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
323 ; CHECK:       cond.false:
324 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[X]], 1
325 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
326 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
327 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
328 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
329 ; CHECK:       trap:
330 ; CHECK-NEXT:    tail call void @llvm.trap()
331 ; CHECK-NEXT:    unreachable
332 ; CHECK:       cond.end:
333 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
334 ; CHECK-NEXT:    ret i32 [[COND]]
336 entry:
337   %cmp = icmp eq i32 %x, -1
338   br i1 %cmp, label %cond.end, label %cond.false
340 cond.false:                                       ; preds = %entry
341   %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 1)
342   %1 = extractvalue { i32, i1 } %0, 0
343   %2 = extractvalue { i32, i1 } %0, 1
344   br i1 %2, label %trap, label %cond.end
346 trap:                                             ; preds = %cond.false
347   tail call void @llvm.trap()
348   unreachable
350 cond.end:                                         ; preds = %cond.false, %entry
351   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
352   ret i32 %cond
355 define i32 @signed_sub_r1(i32 %x) {
356 ; CHECK-LABEL: @signed_sub_r1(
357 ; CHECK-NEXT:  entry:
358 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
359 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
360 ; CHECK:       cond.false:
361 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nsw i32 [[X]], 1
362 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
363 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
364 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
365 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
366 ; CHECK:       trap:
367 ; CHECK-NEXT:    tail call void @llvm.trap()
368 ; CHECK-NEXT:    unreachable
369 ; CHECK:       cond.end:
370 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
371 ; CHECK-NEXT:    ret i32 [[COND]]
373 entry:
374   %cmp = icmp eq i32 %x, -2147483648
375   br i1 %cmp, label %cond.end, label %cond.false
377 cond.false:                                       ; preds = %entry
378   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 1)
379   %1 = extractvalue { i32, i1 } %0, 0
380   %2 = extractvalue { i32, i1 } %0, 1
381   br i1 %2, label %trap, label %cond.end
383 trap:                                             ; preds = %cond.false
384   tail call void @llvm.trap()
385   unreachable
387 cond.end:                                         ; preds = %cond.false, %entry
388   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
389   ret i32 %cond
392 define i32 @unsigned_sub_r1(i32 %x) {
393 ; CHECK-LABEL: @unsigned_sub_r1(
394 ; CHECK-NEXT:  entry:
395 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
396 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
397 ; CHECK:       cond.false:
398 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw i32 [[X]], 1
399 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
400 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
401 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
402 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
403 ; CHECK:       trap:
404 ; CHECK-NEXT:    tail call void @llvm.trap()
405 ; CHECK-NEXT:    unreachable
406 ; CHECK:       cond.end:
407 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
408 ; CHECK-NEXT:    ret i32 [[COND]]
410 entry:
411   %cmp = icmp eq i32 %x, 0
412   br i1 %cmp, label %cond.end, label %cond.false
414 cond.false:                                       ; preds = %entry
415   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 1)
416   %1 = extractvalue { i32, i1 } %0, 0
417   %2 = extractvalue { i32, i1 } %0, 1
418   br i1 %2, label %trap, label %cond.end
420 trap:                                             ; preds = %cond.false
421   tail call void @llvm.trap()
422   unreachable
424 cond.end:                                         ; preds = %cond.false, %entry
425   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
426   ret i32 %cond
429 define i32 @signed_add_rn1(i32 %x) {
430 ; CHECK-LABEL: @signed_add_rn1(
431 ; CHECK-NEXT:  entry:
432 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
433 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
434 ; CHECK:       cond.false:
435 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[X]], -1
436 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
437 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
438 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
439 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
440 ; CHECK:       trap:
441 ; CHECK-NEXT:    tail call void @llvm.trap()
442 ; CHECK-NEXT:    unreachable
443 ; CHECK:       cond.end:
444 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
445 ; CHECK-NEXT:    ret i32 [[COND]]
447 entry:
448   %cmp = icmp eq i32 %x, -2147483648
449   br i1 %cmp, label %cond.end, label %cond.false
451 cond.false:                                       ; preds = %entry
452   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 -1)
453   %1 = extractvalue { i32, i1 } %0, 0
454   %2 = extractvalue { i32, i1 } %0, 1
455   br i1 %2, label %trap, label %cond.end
457 trap:                                             ; preds = %cond.false
458   tail call void @llvm.trap()
459   unreachable
461 cond.end:                                         ; preds = %cond.false, %entry
462   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
463   ret i32 %cond
466 define i32 @signed_sub_rn1(i32 %x) {
467 ; CHECK-LABEL: @signed_sub_rn1(
468 ; CHECK-NEXT:  entry:
469 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
470 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
471 ; CHECK:       cond.false:
472 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nsw i32 [[X]], -1
473 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
474 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
475 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
476 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
477 ; CHECK:       trap:
478 ; CHECK-NEXT:    tail call void @llvm.trap()
479 ; CHECK-NEXT:    unreachable
480 ; CHECK:       cond.end:
481 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
482 ; CHECK-NEXT:    ret i32 [[COND]]
484 entry:
485   %cmp = icmp eq i32 %x, 2147483647
486   br i1 %cmp, label %cond.end, label %cond.false
488 cond.false:                                       ; preds = %entry
489   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 -1)
490   %1 = extractvalue { i32, i1 } %0, 0
491   %2 = extractvalue { i32, i1 } %0, 1
492   br i1 %2, label %trap, label %cond.end
494 trap:                                             ; preds = %cond.false
495   tail call void @llvm.trap()
496   unreachable
498 cond.end:                                         ; preds = %cond.false, %entry
499   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
500   ret i32 %cond
503 define i32 @unsigned_mul(i32 %x) {
504 ; CHECK-LABEL: @unsigned_mul(
505 ; CHECK-NEXT:  entry:
506 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 10000
507 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
508 ; CHECK:       cond.false:
509 ; CHECK-NEXT:    [[MULO1:%.*]] = mul nuw nsw i32 [[X]], 100
510 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[MULO1]], 0
511 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
512 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
513 ; CHECK-NEXT:    br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
514 ; CHECK:       trap:
515 ; CHECK-NEXT:    tail call void @llvm.trap()
516 ; CHECK-NEXT:    unreachable
517 ; CHECK:       cond.end:
518 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[COND_FALSE]] ]
519 ; CHECK-NEXT:    ret i32 [[COND]]
521 entry:
522   %cmp = icmp ugt i32 %x, 10000
523   br i1 %cmp, label %cond.end, label %cond.false
525 cond.false:                                       ; preds = %entry
526   %mulo = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 100)
527   %res = extractvalue { i32, i1 } %mulo, 0
528   %ov = extractvalue { i32, i1 } %mulo, 1
529   br i1 %ov, label %trap, label %cond.end
531 trap:                                             ; preds = %cond.false
532   tail call void @llvm.trap()
533   unreachable
535 cond.end:                                         ; preds = %cond.false, %entry
536   %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
537   ret i32 %cond
540 define i32 @signed_mul(i32 %x) {
541 ; CHECK-LABEL: @signed_mul(
542 ; CHECK-NEXT:  entry:
543 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[X:%.*]], 10000
544 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], -10000
545 ; CHECK-NEXT:    [[CMP3:%.*]] = or i1 [[CMP1]], [[CMP2]]
546 ; CHECK-NEXT:    br i1 [[CMP3]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
547 ; CHECK:       cond.false:
548 ; CHECK-NEXT:    [[MULO1:%.*]] = mul nsw i32 [[X]], 100
549 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[MULO1]], 0
550 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
551 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
552 ; CHECK-NEXT:    br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
553 ; CHECK:       trap:
554 ; CHECK-NEXT:    tail call void @llvm.trap()
555 ; CHECK-NEXT:    unreachable
556 ; CHECK:       cond.end:
557 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[COND_FALSE]] ]
558 ; CHECK-NEXT:    ret i32 [[COND]]
560 entry:
561   %cmp1 = icmp sgt i32 %x, 10000
562   %cmp2 = icmp slt i32 %x, -10000
563   %cmp3 = or i1 %cmp1, %cmp2
564   br i1 %cmp3, label %cond.end, label %cond.false
566 cond.false:                                       ; preds = %entry
567   %mulo = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 100)
568   %res = extractvalue { i32, i1 } %mulo, 0
569   %ov = extractvalue { i32, i1 } %mulo, 1
570   br i1 %ov, label %trap, label %cond.end
572 trap:                                             ; preds = %cond.false
573   tail call void @llvm.trap()
574   unreachable
576 cond.end:                                         ; preds = %cond.false, %entry
577   %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
578   ret i32 %cond
581 declare i32 @bar(i32)
583 define void @unsigned_loop(i32 %i) {
584 ; CHECK-LABEL: @unsigned_loop(
585 ; CHECK-NEXT:  entry:
586 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[I:%.*]], 0
587 ; CHECK-NEXT:    br i1 [[CMP3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
588 ; CHECK:       while.body.preheader:
589 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
590 ; CHECK:       while.body:
591 ; CHECK-NEXT:    [[I_ADDR_04:%.*]] = phi i32 [ [[TMP3:%.*]], [[CONT:%.*]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
592 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @bar(i32 [[I_ADDR_04]])
593 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw i32 [[I_ADDR_04]], 1
594 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
595 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
596 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT]]
597 ; CHECK:       trap:
598 ; CHECK-NEXT:    tail call void @llvm.trap()
599 ; CHECK-NEXT:    unreachable
600 ; CHECK:       cont:
601 ; CHECK-NEXT:    [[TMP3]] = extractvalue { i32, i1 } [[TMP1]], 0
602 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP3]], 0
603 ; CHECK-NEXT:    br i1 [[CMP]], label [[WHILE_END]], label [[WHILE_BODY]]
604 ; CHECK:       while.end:
605 ; CHECK-NEXT:    ret void
607 entry:
608   %cmp3 = icmp eq i32 %i, 0
609   br i1 %cmp3, label %while.end, label %while.body.preheader
611 while.body.preheader:                             ; preds = %entry
612   br label %while.body
614 while.body:                                       ; preds = %while.body.preheader, %cont
615   %i.addr.04 = phi i32 [ %2, %cont ], [ %i, %while.body.preheader ]
616   %call = tail call i32 @bar(i32 %i.addr.04)
617   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.addr.04, i32 1)
618   %1 = extractvalue { i32, i1 } %0, 1
619   br i1 %1, label %trap, label %cont
621 trap:                                             ; preds = %while.body
622   tail call void @llvm.trap()
623   unreachable
625 cont:                                             ; preds = %while.body
626   %2 = extractvalue { i32, i1 } %0, 0
627   %cmp = icmp eq i32 %2, 0
628   br i1 %cmp, label %while.end, label %while.body
630 while.end:                                        ; preds = %cont, %entry
631   ret void
634 define void @intrinsic_into_phi(i32 %n) {
635 ; CHECK-LABEL: @intrinsic_into_phi(
636 ; CHECK-NEXT:  entry:
637 ; CHECK-NEXT:    br label [[CONT:%.*]]
638 ; CHECK:       for.cond:
639 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[DOTLCSSA:%.*]], 1
640 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
641 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
642 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT]]
643 ; CHECK:       trap:
644 ; CHECK-NEXT:    tail call void @llvm.trap()
645 ; CHECK-NEXT:    unreachable
646 ; CHECK:       cont:
647 ; CHECK-NEXT:    [[TMP3:%.*]] = phi { i32, i1 } [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP1]], [[FOR_COND:%.*]] ]
648 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0
649 ; CHECK-NEXT:    [[CALL9:%.*]] = tail call i32 @bar(i32 [[TMP4]])
650 ; CHECK-NEXT:    [[TOBOOL10:%.*]] = icmp eq i32 [[CALL9]], 0
651 ; CHECK-NEXT:    br i1 [[TOBOOL10]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
652 ; CHECK:       while.body.preheader:
653 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
654 ; CHECK:       while.cond:
655 ; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP7:%.*]], 0
656 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @bar(i32 [[TMP5]])
657 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[CALL]], 0
658 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END]], label [[WHILE_BODY]]
659 ; CHECK:       while.body:
660 ; CHECK-NEXT:    [[TMP6:%.*]] = phi i32 [ [[TMP5]], [[WHILE_COND:%.*]] ], [ [[TMP4]], [[WHILE_BODY_PREHEADER]] ]
661 ; CHECK-NEXT:    [[TMP7]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP6]], i32 1)
662 ; CHECK-NEXT:    [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
663 ; CHECK-NEXT:    br i1 [[TMP8]], label [[TRAP]], label [[WHILE_COND]]
664 ; CHECK:       while.end:
665 ; CHECK-NEXT:    [[DOTLCSSA]] = phi i32 [ [[TMP4]], [[CONT]] ], [ [[TMP5]], [[WHILE_COND]] ]
666 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[DOTLCSSA]], [[N:%.*]]
667 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND]], label [[CLEANUP2:%.*]]
668 ; CHECK:       cleanup2:
669 ; CHECK-NEXT:    ret void
671 entry:
672   br label %cont
674 for.cond:                                         ; preds = %while.end
675   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %.lcssa, i32 1)
676   %1 = extractvalue { i32, i1 } %0, 1
677   br i1 %1, label %trap, label %cont
679 trap:                                             ; preds = %for.cond, %while.body
680   tail call void @llvm.trap()
681   unreachable
683 cont:                                             ; preds = %entry, %for.cond
684   %2 = phi { i32, i1 } [ zeroinitializer, %entry ], [ %0, %for.cond ]
685   %3 = extractvalue { i32, i1 } %2, 0
686   %call9 = tail call i32 @bar(i32 %3)
687   %tobool10 = icmp eq i32 %call9, 0
688   br i1 %tobool10, label %while.end, label %while.body.preheader
690 while.body.preheader:                             ; preds = %cont
691   br label %while.body
693 while.cond:                                       ; preds = %while.body
694   %4 = extractvalue { i32, i1 } %6, 0
695   %call = tail call i32 @bar(i32 %4)
696   %tobool = icmp eq i32 %call, 0
697   br i1 %tobool, label %while.end, label %while.body
699 while.body:                                       ; preds = %while.body.preheader, %while.cond
700   %5 = phi i32 [ %4, %while.cond ], [ %3, %while.body.preheader ]
701   %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %5, i32 1)
702   %7 = extractvalue { i32, i1 } %6, 1
703   br i1 %7, label %trap, label %while.cond
705 while.end:                                        ; preds = %while.cond, %cont
706   %.lcssa = phi i32 [ %3, %cont ], [ %4, %while.cond ]
707   %cmp = icmp slt i32 %.lcssa, %n
708   br i1 %cmp, label %for.cond, label %cleanup2
710 cleanup2:                                         ; preds = %while.end
711   ret void
714 define { i8, i1 } @signed_mul_constant_folding() {
715 ; CHECK-LABEL: @signed_mul_constant_folding(
716 ; CHECK-NEXT:    ret { i8, i1 } { i8 2, i1 false }
718   %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 1, i8 2)
719   ret { i8, i1 } %mul
722 define { <2 x i32>, <2 x i1> } @uaddo_vec(<2 x i32> %a) {
723 ; CHECK-LABEL: @uaddo_vec(
724 ; CHECK-NEXT:    [[ADD:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[A:%.*]], <2 x i32> <i32 1, i32 1>)
725 ; CHECK-NEXT:    ret { <2 x i32>, <2 x i1> } [[ADD]]
727   %add = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> %a, <2 x i32> <i32 1, i32 1>)
728   ret { <2 x i32>, <2 x i1> } %add
732 define i8 @uadd_sat_no_unsigned_overflow(i8 %x) {
733 ; CHECK-LABEL: @uadd_sat_no_unsigned_overflow(
734 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 100
735 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
736 ; CHECK:       trap:
737 ; CHECK-NEXT:    call void @llvm.trap()
738 ; CHECK-NEXT:    unreachable
739 ; CHECK:       cont:
740 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw i8 [[X]], 100
741 ; CHECK-NEXT:    ret i8 [[RES1]]
743   %cmp = icmp ugt i8 %x, 100
744   br i1 %cmp, label %trap, label %cont
746 trap:
747   call void @llvm.trap()
748   unreachable
750 cont:
751   %res = call i8 @llvm.uadd.sat.i8(i8 %x, i8 100)
752   ret i8 %res
755 define i8 @uadd_sat_no_overflow(i8 %x) {
756 ; CHECK-LABEL: @uadd_sat_no_overflow(
757 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 27
758 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
759 ; CHECK:       trap:
760 ; CHECK-NEXT:    call void @llvm.trap()
761 ; CHECK-NEXT:    unreachable
762 ; CHECK:       cont:
763 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw i8 [[X]], 100
764 ; CHECK-NEXT:    ret i8 [[RES1]]
766   %cmp = icmp ugt i8 %x, 27
767   br i1 %cmp, label %trap, label %cont
769 trap:
770   call void @llvm.trap()
771   unreachable
773 cont:
774   %res = call i8 @llvm.uadd.sat.i8(i8 %x, i8 100)
775   ret i8 %res
778 define i8 @sadd_sat_no_signed_overflow(i8 %x) {
779 ; CHECK-LABEL: @sadd_sat_no_signed_overflow(
780 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 100
781 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
782 ; CHECK:       trap:
783 ; CHECK-NEXT:    call void @llvm.trap()
784 ; CHECK-NEXT:    unreachable
785 ; CHECK:       cont:
786 ; CHECK-NEXT:    [[RES1:%.*]] = add nsw i8 [[X]], 20
787 ; CHECK-NEXT:    ret i8 [[RES1]]
789   %cmp = icmp sgt i8 %x, 100
790   br i1 %cmp, label %trap, label %cont
792 trap:
793   call void @llvm.trap()
794   unreachable
796 cont:
797   %res = call i8 @llvm.sadd.sat.i8(i8 %x, i8 20)
798   ret i8 %res
801 define i8 @sadd_sat_no_overflow(i8 %x) {
802 ; CHECK-LABEL: @sadd_sat_no_overflow(
803 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 107
804 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
805 ; CHECK:       trap:
806 ; CHECK-NEXT:    call void @llvm.trap()
807 ; CHECK-NEXT:    unreachable
808 ; CHECK:       cont:
809 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw i8 [[X]], 20
810 ; CHECK-NEXT:    ret i8 [[RES1]]
812   %cmp = icmp ugt i8 %x, 107
813   br i1 %cmp, label %trap, label %cont
815 trap:
816   call void @llvm.trap()
817   unreachable
819 cont:
820   %res = call i8 @llvm.sadd.sat.i8(i8 %x, i8 20)
821   ret i8 %res
824 define i8 @usub_sat_no_unsigned_overflow(i8 %x) {
825 ; CHECK-LABEL: @usub_sat_no_unsigned_overflow(
826 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], 100
827 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
828 ; CHECK:       trap:
829 ; CHECK-NEXT:    call void @llvm.trap()
830 ; CHECK-NEXT:    unreachable
831 ; CHECK:       cont:
832 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw i8 [[X]], 100
833 ; CHECK-NEXT:    ret i8 [[RES1]]
835   %cmp = icmp ult i8 %x, 100
836   br i1 %cmp, label %trap, label %cont
838 trap:
839   call void @llvm.trap()
840   unreachable
842 cont:
843   %res = call i8 @llvm.usub.sat.i8(i8 %x, i8 100)
844   ret i8 %res
847 define i8 @usub_sat_no_overflow(i8 %x) {
848 ; CHECK-LABEL: @usub_sat_no_overflow(
849 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], -28
850 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
851 ; CHECK:       trap:
852 ; CHECK-NEXT:    call void @llvm.trap()
853 ; CHECK-NEXT:    unreachable
854 ; CHECK:       cont:
855 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i8 [[X]], 100
856 ; CHECK-NEXT:    ret i8 [[RES1]]
858   %cmp = icmp ult i8 %x, 228
859   br i1 %cmp, label %trap, label %cont
861 trap:
862   call void @llvm.trap()
863   unreachable
865 cont:
866   %res = call i8 @llvm.usub.sat.i8(i8 %x, i8 100)
867   ret i8 %res
870 define i8 @ssub_sat_no_signed_overflow(i8 %x) {
871 ; CHECK-LABEL: @ssub_sat_no_signed_overflow(
872 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -100
873 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
874 ; CHECK:       trap:
875 ; CHECK-NEXT:    call void @llvm.trap()
876 ; CHECK-NEXT:    unreachable
877 ; CHECK:       cont:
878 ; CHECK-NEXT:    [[RES1:%.*]] = sub nsw i8 [[X]], 20
879 ; CHECK-NEXT:    ret i8 [[RES1]]
881   %cmp = icmp slt i8 %x, -100
882   br i1 %cmp, label %trap, label %cont
884 trap:
885   call void @llvm.trap()
886   unreachable
888 cont:
889   %res = call i8 @llvm.ssub.sat.i8(i8 %x, i8 20)
890   ret i8 %res
893 define i8 @ssub_sat_no_overflow(i8 %x) {
894 ; CHECK-LABEL: @ssub_sat_no_overflow(
895 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], -108
896 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
897 ; CHECK:       trap:
898 ; CHECK-NEXT:    call void @llvm.trap()
899 ; CHECK-NEXT:    unreachable
900 ; CHECK:       cont:
901 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i8 [[X]], 20
902 ; CHECK-NEXT:    ret i8 [[RES1]]
904   %cmp = icmp ult i8 %x, 148
905   br i1 %cmp, label %trap, label %cont
907 trap:
908   call void @llvm.trap()
909   unreachable
911 cont:
912   %res = call i8 @llvm.ssub.sat.i8(i8 %x, i8 20)
913   ret i8 %res
916 define <2 x i8> @uadd_sat_vec(<2 x i8> %a) {
917 ; CHECK-LABEL: @uadd_sat_vec(
918 ; CHECK-NEXT:    [[ADD:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 1, i8 1>)
919 ; CHECK-NEXT:    ret <2 x i8> [[ADD]]
921   %add = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 1, i8 1>)
922   ret <2 x i8> %add
925 ; In the following tests, we should first simplify a with.overflow intrinsic
926 ; to a simple arithmetic operation and insertvalue, but also simplify the
927 ; subsequent comparison that is based on it.
929 define i1 @sadd_and_cmp(i32 %x, i32 %y) #0 {
930 ; CHECK-LABEL: @sadd_and_cmp(
931 ; CHECK-NEXT:  entry:
932 ; CHECK-NEXT:    [[X_OFFSET:%.*]] = add i32 [[X:%.*]], 9
933 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X_OFFSET]], 19
934 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
935 ; CHECK:       cont1:
936 ; CHECK-NEXT:    [[Y_OFFSET:%.*]] = add i32 [[Y:%.*]], 9
937 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y_OFFSET]], 19
938 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
939 ; CHECK:       cont2:
940 ; CHECK-NEXT:    [[RES1:%.*]] = add nsw i32 [[X]], [[Y]]
941 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
942 ; CHECK-NEXT:    [[ADD:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
943 ; CHECK-NEXT:    br label [[CONT3:%.*]]
944 ; CHECK:       cont3:
945 ; CHECK-NEXT:    br label [[OUT]]
946 ; CHECK:       out:
947 ; CHECK-NEXT:    ret i1 true
949 entry:
950   %x.offset = add i32 %x, 9
951   %cmp1 = icmp ult i32 %x.offset, 19
952   br i1 %cmp1, label %cont1, label %out
954 cont1:
955   %y.offset = add i32 %y, 9
956   %cmp2 = icmp ult i32 %y.offset, 19
957   br i1 %cmp2, label %cont2, label %out
959 cont2:
960   ; x = [-9,10), y = [-9,10)
961   %res = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
962   %add = extractvalue { i32, i1 } %res, 0
963   br label %cont3
965 cont3:
966   ; add = [-18,19)
967   %cmp3 = icmp slt i32 %add, 19
968   br label %out
970 out:
971   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
972   ret i1 %ret
976 define i1 @uadd_and_cmp(i32 %x, i32 %y) #0 {
977 ; CHECK-LABEL: @uadd_and_cmp(
978 ; CHECK-NEXT:  entry:
979 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
980 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
981 ; CHECK:       cont1:
982 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
983 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
984 ; CHECK:       cont2:
985 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw i32 [[X]], [[Y]]
986 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
987 ; CHECK-NEXT:    [[ADD:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
988 ; CHECK-NEXT:    br label [[CONT3:%.*]]
989 ; CHECK:       cont3:
990 ; CHECK-NEXT:    br label [[OUT]]
991 ; CHECK:       out:
992 ; CHECK-NEXT:    ret i1 true
994 entry:
995   %cmp1 = icmp ult i32 %x, 10
996   br i1 %cmp1, label %cont1, label %out
998 cont1:
999   %cmp2 = icmp ult i32 %y, 10
1000   br i1 %cmp2, label %cont2, label %out
1002 cont2:
1003   %res = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
1004   %add = extractvalue { i32, i1 } %res, 0
1005   br label %cont3
1007 cont3:
1008   %cmp3 = icmp ult i32 %add, 19
1009   br label %out
1011 out:
1012   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
1013   ret i1 %ret
1016 define i1 @ssub_and_cmp(i32 %x, i32 %y) #0 {
1017 ; CHECK-LABEL: @ssub_and_cmp(
1018 ; CHECK-NEXT:  entry:
1019 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
1020 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1021 ; CHECK:       cont1:
1022 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
1023 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1024 ; CHECK:       cont2:
1025 ; CHECK-NEXT:    [[OFFSET:%.*]] = add nuw nsw i32 [[X]], 9
1026 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i32 [[OFFSET]], [[Y]]
1027 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1028 ; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1029 ; CHECK-NEXT:    br label [[CONT3:%.*]]
1030 ; CHECK:       cont3:
1031 ; CHECK-NEXT:    br label [[OUT]]
1032 ; CHECK:       out:
1033 ; CHECK-NEXT:    ret i1 true
1035 entry:
1036   %cmp1 = icmp ult i32 %x, 10
1037   br i1 %cmp1, label %cont1, label %out
1039 cont1:
1040   %cmp2 = icmp ult i32 %y, 10
1041   br i1 %cmp2, label %cont2, label %out
1043 cont2:
1044   %offset = add i32 %x, 9
1045   ; x = [0,10), y = [0,10), offset = [9,19)
1046   %res = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %offset, i32 %y)
1047   %sub = extractvalue { i32, i1 } %res, 0
1048   br label %cont3
1050 cont3:
1051   %cmp3 = icmp ult i32 %sub, 19
1052   br label %out
1054 out:
1055   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
1056   ret i1 %ret
1059 define i1 @usub_and_cmp(i32 %x, i32 %y) #0 {
1060 ; CHECK-LABEL: @usub_and_cmp(
1061 ; CHECK-NEXT:  entry:
1062 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
1063 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1064 ; CHECK:       cont1:
1065 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
1066 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1067 ; CHECK:       cont2:
1068 ; CHECK-NEXT:    [[OFFSET:%.*]] = add nuw nsw i32 [[X]], 9
1069 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i32 [[OFFSET]], [[Y]]
1070 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1071 ; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1072 ; CHECK-NEXT:    br label [[CONT3:%.*]]
1073 ; CHECK:       cont3:
1074 ; CHECK-NEXT:    br label [[OUT]]
1075 ; CHECK:       out:
1076 ; CHECK-NEXT:    ret i1 true
1078 entry:
1079   %cmp1 = icmp ult i32 %x, 10
1080   br i1 %cmp1, label %cont1, label %out
1082 cont1:
1083   %cmp2 = icmp ult i32 %y, 10
1084   br i1 %cmp2, label %cont2, label %out
1086 cont2:
1087   %offset = add i32 %x, 9
1088   ; x = [0,10), y = [0,10), offset = [9,19)
1089   %res = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %offset, i32 %y)
1090   %sub = extractvalue { i32, i1 } %res, 0
1091   br label %cont3
1093 cont3:
1094   %cmp3 = icmp ult i32 %sub, 19
1095   br label %out
1097 out:
1098   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
1099   ret i1 %ret
1102 define i1 @smul_and_cmp(i32 %x, i32 %y) #0 {
1103 ; CHECK-LABEL: @smul_and_cmp(
1104 ; CHECK-NEXT:  entry:
1105 ; CHECK-NEXT:    [[X_OFFSET:%.*]] = add i32 [[X:%.*]], 9
1106 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X_OFFSET]], 19
1107 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1108 ; CHECK:       cont1:
1109 ; CHECK-NEXT:    [[Y_OFFSET:%.*]] = add i32 [[Y:%.*]], 9
1110 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y_OFFSET]], 19
1111 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1112 ; CHECK:       cont2:
1113 ; CHECK-NEXT:    [[RES1:%.*]] = mul nsw i32 [[X]], [[Y]]
1114 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1115 ; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1116 ; CHECK-NEXT:    br label [[CONT3:%.*]]
1117 ; CHECK:       cont3:
1118 ; CHECK-NEXT:    br label [[OUT]]
1119 ; CHECK:       out:
1120 ; CHECK-NEXT:    ret i1 true
1122 entry:
1123   %x.offset = add i32 %x, 9
1124   %cmp1 = icmp ult i32 %x.offset, 19
1125   br i1 %cmp1, label %cont1, label %out
1127 cont1:
1128   %y.offset = add i32 %y, 9
1129   %cmp2 = icmp ult i32 %y.offset, 19
1130   br i1 %cmp2, label %cont2, label %out
1132 cont2:
1133   ; x = [-9,10), y = [-9,10)
1134   %res = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 %y)
1135   %mul = extractvalue { i32, i1 } %res, 0
1136   br label %cont3
1138 cont3:
1139   %cmp3 = icmp sle i32 %mul, 81
1140   %cmp4 = icmp sge i32 %mul, -81
1141   %cmp5 = and i1 %cmp3, %cmp4
1142   br label %out
1144 out:
1145   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp5, %cont3 ]
1146   ret i1 %ret
1149 define i1 @umul_and_cmp(i32 %x, i32 %y) #0 {
1150 ; CHECK-LABEL: @umul_and_cmp(
1151 ; CHECK-NEXT:  entry:
1152 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 100
1153 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1154 ; CHECK:       cont1:
1155 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 100
1156 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1157 ; CHECK:       cont2:
1158 ; CHECK-NEXT:    [[RES1:%.*]] = mul nuw nsw i32 [[X]], [[Y]]
1159 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1160 ; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1161 ; CHECK-NEXT:    br label [[CONT3:%.*]]
1162 ; CHECK:       cont3:
1163 ; CHECK-NEXT:    br label [[OUT]]
1164 ; CHECK:       out:
1165 ; CHECK-NEXT:    ret i1 true
1167 entry:
1168   %cmp1 = icmp ult i32 %x, 100
1169   br i1 %cmp1, label %cont1, label %out
1171 cont1:
1172   %cmp2 = icmp ult i32 %y, 100
1173   br i1 %cmp2, label %cont2, label %out
1175 cont2:
1176   %res = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
1177   %mul = extractvalue { i32, i1 } %res, 0
1178   br label %cont3
1180 cont3:
1181   %cmp3 = icmp ule i32 %mul, 9801
1182   br label %out
1184 out:
1185   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
1186   ret i1 %ret