[ARM] MVE big endian bitcasts
[llvm-complete.git] / test / Transforms / CorrelatedValuePropagation / overflows.ll
blob04b1471ebb44eaf96cbb321bc749b449b3234960
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 nsw i32 2147483647, [[Y]]
42 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
43 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
44 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
45 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT:%.*]]
46 ; CHECK:       trap:
47 ; CHECK-NEXT:    tail call void @llvm.trap()
48 ; CHECK-NEXT:    unreachable
49 ; CHECK:       cont:
50 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
51 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[TMP4]], [[X:%.*]]
52 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
53 ; CHECK:       lor.lhs.false:
54 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[Y]], 0
55 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LAND_LHS_TRUE3:%.*]], label [[COND_FALSE]]
56 ; CHECK:       land.lhs.true3:
57 ; CHECK-NEXT:    [[TMP5:%.*]] = sub nsw i32 -2147483648, [[Y]]
58 ; CHECK-NEXT:    [[TMP6:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP5]], 0
59 ; CHECK-NEXT:    [[TMP7:%.*]] = insertvalue { i32, i1 } [[TMP6]], i1 false, 1
60 ; CHECK-NEXT:    [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
61 ; CHECK-NEXT:    br i1 [[TMP8]], label [[TRAP]], label [[CONT4:%.*]]
62 ; CHECK:       cont4:
63 ; CHECK-NEXT:    [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP7]], 0
64 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[TMP9]], [[X]]
65 ; CHECK-NEXT:    br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
66 ; CHECK:       cond.false:
67 ; CHECK-NEXT:    [[TMP10:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
68 ; CHECK-NEXT:    [[TMP11:%.*]] = extractvalue { i32, i1 } [[TMP10]], 0
69 ; CHECK-NEXT:    [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP10]], 1
70 ; CHECK-NEXT:    br i1 [[TMP12]], label [[TRAP]], label [[COND_END]]
71 ; CHECK:       cond.end:
72 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP11]], [[COND_FALSE]] ]
73 ; CHECK-NEXT:    ret i32 [[COND]]
75 entry:
76   %cmp = icmp sgt i32 %y, 0
77   br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
79 land.lhs.true:                                    ; preds = %entry
80   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 2147483647, i32 %y)
81   %1 = extractvalue { i32, i1 } %0, 1
82   br i1 %1, label %trap, label %cont
84 trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
85   tail call void @llvm.trap()
86   unreachable
88 cont:                                             ; preds = %land.lhs.true
89   %2 = extractvalue { i32, i1 } %0, 0
90   %cmp1 = icmp slt i32 %2, %x
91   br i1 %cmp1, label %cond.end, label %cond.false
93 lor.lhs.false:                                    ; preds = %entry
94   %cmp2 = icmp slt i32 %y, 0
95   br i1 %cmp2, label %land.lhs.true3, label %cond.false
97 land.lhs.true3:                                   ; preds = %lor.lhs.false
98   %3 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 -2147483648, i32 %y)
99   %4 = extractvalue { i32, i1 } %3, 1
100   br i1 %4, label %trap, label %cont4
102 cont4:                                            ; preds = %land.lhs.true3
103   %5 = extractvalue { i32, i1 } %3, 0
104   %cmp5 = icmp sgt i32 %5, %x
105   br i1 %cmp5, label %cond.end, label %cond.false
107 cond.false:                                       ; preds = %cont, %cont4, %lor.lhs.false
108   %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
109   %7 = extractvalue { i32, i1 } %6, 0
110   %8 = extractvalue { i32, i1 } %6, 1
111   br i1 %8, label %trap, label %cond.end
113 cond.end:                                         ; preds = %cond.false, %cont, %cont4
114   %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
115   ret i32 %cond
118 define i32 @unsigned_add(i32 %x, i32 %y) {
119 ; CHECK-LABEL: @unsigned_add(
120 ; CHECK-NEXT:  entry:
121 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw i32 -1, [[Y:%.*]]
122 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
123 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
124 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
125 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT:%.*]]
126 ; CHECK:       trap:
127 ; CHECK-NEXT:    tail call void @llvm.trap()
128 ; CHECK-NEXT:    unreachable
129 ; CHECK:       cont:
130 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
131 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[TMP4]], [[X:%.*]]
132 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
133 ; CHECK:       cond.false:
134 ; CHECK-NEXT:    [[TMP5:%.*]] = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
135 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
136 ; CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
137 ; CHECK-NEXT:    br i1 [[TMP7]], label [[TRAP]], label [[COND_END]]
138 ; CHECK:       cond.end:
139 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT]] ], [ [[TMP6]], [[COND_FALSE]] ]
140 ; CHECK-NEXT:    ret i32 [[COND]]
142 entry:
143   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y)
144   %1 = extractvalue { i32, i1 } %0, 1
145   br i1 %1, label %trap, label %cont
147 trap:                                             ; preds = %cond.false, %entry
148   tail call void @llvm.trap()
149   unreachable
151 cont:                                             ; preds = %entry
152   %2 = extractvalue { i32, i1 } %0, 0
153   %cmp1 = icmp ult i32 %2, %x
154   br i1 %cmp1, label %cond.end, label %cond.false
156 cond.false:                                       ; preds = %cont
157   %3 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
158   %4 = extractvalue { i32, i1 } %3, 0
159   %5 = extractvalue { i32, i1 } %3, 1
160   br i1 %5, label %trap, label %cond.end
162 cond.end:                                         ; preds = %cond.false, %cont
163   %cond = phi i32 [ 0, %cont ], [ %4, %cond.false ]
164   ret i32 %cond
167 define i32 @signed_sub(i32 %x, i32 %y) {
168 ; CHECK-LABEL: @signed_sub(
169 ; CHECK-NEXT:  entry:
170 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[Y:%.*]], 0
171 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_LHS_FALSE:%.*]]
172 ; CHECK:       land.lhs.true:
173 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[Y]], 2147483647
174 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
175 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
176 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
177 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT:%.*]]
178 ; CHECK:       trap:
179 ; CHECK-NEXT:    tail call void @llvm.trap()
180 ; CHECK-NEXT:    unreachable
181 ; CHECK:       cont:
182 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
183 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[TMP4]], [[X:%.*]]
184 ; CHECK-NEXT:    br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
185 ; CHECK:       lor.lhs.false:
186 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
187 ; CHECK-NEXT:    br i1 [[CMP2]], label [[COND_FALSE]], label [[LAND_LHS_TRUE3:%.*]]
188 ; CHECK:       land.lhs.true3:
189 ; CHECK-NEXT:    [[TMP5:%.*]] = add nsw i32 [[Y]], -2147483648
190 ; CHECK-NEXT:    [[TMP6:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP5]], 0
191 ; CHECK-NEXT:    [[TMP7:%.*]] = insertvalue { i32, i1 } [[TMP6]], i1 false, 1
192 ; CHECK-NEXT:    [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
193 ; CHECK-NEXT:    br i1 [[TMP8]], label [[TRAP]], label [[CONT4:%.*]]
194 ; CHECK:       cont4:
195 ; CHECK-NEXT:    [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP7]], 0
196 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[TMP9]], [[X]]
197 ; CHECK-NEXT:    br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
198 ; CHECK:       cond.false:
199 ; CHECK-NEXT:    [[TMP10:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[X]], i32 [[Y]])
200 ; CHECK-NEXT:    [[TMP11:%.*]] = extractvalue { i32, i1 } [[TMP10]], 0
201 ; CHECK-NEXT:    [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP10]], 1
202 ; CHECK-NEXT:    br i1 [[TMP12]], label [[TRAP]], label [[COND_END]]
203 ; CHECK:       cond.end:
204 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP11]], [[COND_FALSE]] ]
205 ; CHECK-NEXT:    ret i32 [[COND]]
207 entry:
208   %cmp = icmp slt i32 %y, 0
209   br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
211 land.lhs.true:                                    ; preds = %entry
212   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 2147483647)
213   %1 = extractvalue { i32, i1 } %0, 1
214   br i1 %1, label %trap, label %cont
216 trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
217   tail call void @llvm.trap()
218   unreachable
220 cont:                                             ; preds = %land.lhs.true
221   %2 = extractvalue { i32, i1 } %0, 0
222   %cmp1 = icmp slt i32 %2, %x
223   br i1 %cmp1, label %cond.end, label %cond.false
225 lor.lhs.false:                                    ; preds = %entry
226   %cmp2 = icmp eq i32 %y, 0
227   br i1 %cmp2, label %cond.false, label %land.lhs.true3
229 land.lhs.true3:                                   ; preds = %lor.lhs.false
230   %3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 -2147483648)
231   %4 = extractvalue { i32, i1 } %3, 1
232   br i1 %4, label %trap, label %cont4
234 cont4:                                            ; preds = %land.lhs.true3
235   %5 = extractvalue { i32, i1 } %3, 0
236   %cmp5 = icmp sgt i32 %5, %x
237   br i1 %cmp5, label %cond.end, label %cond.false
239 cond.false:                                       ; preds = %lor.lhs.false, %cont, %cont4
240   %6 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
241   %7 = extractvalue { i32, i1 } %6, 0
242   %8 = extractvalue { i32, i1 } %6, 1
243   br i1 %8, label %trap, label %cond.end
245 cond.end:                                         ; preds = %cond.false, %cont, %cont4
246   %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
247   ret i32 %cond
250 define i32 @unsigned_sub(i32 %x, i32 %y) {
251 ; CHECK-LABEL: @unsigned_sub(
252 ; CHECK-NEXT:  entry:
253 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
254 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
255 ; CHECK:       cond.false:
256 ; CHECK-NEXT:    [[TMP0:%.*]] = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X]], i32 [[Y]])
257 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
258 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
259 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TRAP:%.*]], label [[COND_END]]
260 ; CHECK:       trap:
261 ; CHECK-NEXT:    tail call void @llvm.trap()
262 ; CHECK-NEXT:    unreachable
263 ; CHECK:       cond.end:
264 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1]], [[COND_FALSE]] ]
265 ; CHECK-NEXT:    ret i32 [[COND]]
267 entry:
268   %cmp = icmp ult i32 %x, %y
269   br i1 %cmp, label %cond.end, label %cond.false
271 cond.false:                                       ; preds = %entry
272   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
273   %1 = extractvalue { i32, i1 } %0, 0
274   %2 = extractvalue { i32, i1 } %0, 1
275   br i1 %2, label %trap, label %cond.end
277 trap:                                             ; preds = %cond.false
278   tail call void @llvm.trap()
279   unreachable
281 cond.end:                                         ; preds = %cond.false, %entry
282   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
283   ret i32 %cond
286 define i32 @signed_add_r1(i32 %x) {
287 ; CHECK-LABEL: @signed_add_r1(
288 ; CHECK-NEXT:  entry:
289 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
290 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
291 ; CHECK:       cond.false:
292 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[X]], 1
293 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
294 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
295 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
296 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
297 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
298 ; CHECK:       trap:
299 ; CHECK-NEXT:    tail call void @llvm.trap()
300 ; CHECK-NEXT:    unreachable
301 ; CHECK:       cond.end:
302 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
303 ; CHECK-NEXT:    ret i32 [[COND]]
305 entry:
306   %cmp = icmp eq i32 %x, 2147483647
307   br i1 %cmp, label %cond.end, label %cond.false
309 cond.false:                                       ; preds = %entry
310   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
311   %1 = extractvalue { i32, i1 } %0, 0
312   %2 = extractvalue { i32, i1 } %0, 1
313   br i1 %2, label %trap, label %cond.end
315 trap:                                             ; preds = %cond.false
316   tail call void @llvm.trap()
317   unreachable
319 cond.end:                                         ; preds = %cond.false, %entry
320   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
321   ret i32 %cond
324 define i32 @unsigned_add_r1(i32 %x) {
325 ; CHECK-LABEL: @unsigned_add_r1(
326 ; CHECK-NEXT:  entry:
327 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -1
328 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
329 ; CHECK:       cond.false:
330 ; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[X]], 1
331 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
332 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
333 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
334 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
335 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
336 ; CHECK:       trap:
337 ; CHECK-NEXT:    tail call void @llvm.trap()
338 ; CHECK-NEXT:    unreachable
339 ; CHECK:       cond.end:
340 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
341 ; CHECK-NEXT:    ret i32 [[COND]]
343 entry:
344   %cmp = icmp eq i32 %x, -1
345   br i1 %cmp, label %cond.end, label %cond.false
347 cond.false:                                       ; preds = %entry
348   %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 1)
349   %1 = extractvalue { i32, i1 } %0, 0
350   %2 = extractvalue { i32, i1 } %0, 1
351   br i1 %2, label %trap, label %cond.end
353 trap:                                             ; preds = %cond.false
354   tail call void @llvm.trap()
355   unreachable
357 cond.end:                                         ; preds = %cond.false, %entry
358   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
359   ret i32 %cond
362 define i32 @signed_sub_r1(i32 %x) {
363 ; CHECK-LABEL: @signed_sub_r1(
364 ; CHECK-NEXT:  entry:
365 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
366 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
367 ; CHECK:       cond.false:
368 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nsw i32 [[X]], 1
369 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
370 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
371 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
372 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
373 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
374 ; CHECK:       trap:
375 ; CHECK-NEXT:    tail call void @llvm.trap()
376 ; CHECK-NEXT:    unreachable
377 ; CHECK:       cond.end:
378 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
379 ; CHECK-NEXT:    ret i32 [[COND]]
381 entry:
382   %cmp = icmp eq i32 %x, -2147483648
383   br i1 %cmp, label %cond.end, label %cond.false
385 cond.false:                                       ; preds = %entry
386   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 1)
387   %1 = extractvalue { i32, i1 } %0, 0
388   %2 = extractvalue { i32, i1 } %0, 1
389   br i1 %2, label %trap, label %cond.end
391 trap:                                             ; preds = %cond.false
392   tail call void @llvm.trap()
393   unreachable
395 cond.end:                                         ; preds = %cond.false, %entry
396   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
397   ret i32 %cond
400 define i32 @unsigned_sub_r1(i32 %x) {
401 ; CHECK-LABEL: @unsigned_sub_r1(
402 ; CHECK-NEXT:  entry:
403 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
404 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
405 ; CHECK:       cond.false:
406 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw i32 [[X]], 1
407 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
408 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
409 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
410 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
411 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
412 ; CHECK:       trap:
413 ; CHECK-NEXT:    tail call void @llvm.trap()
414 ; CHECK-NEXT:    unreachable
415 ; CHECK:       cond.end:
416 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
417 ; CHECK-NEXT:    ret i32 [[COND]]
419 entry:
420   %cmp = icmp eq i32 %x, 0
421   br i1 %cmp, label %cond.end, label %cond.false
423 cond.false:                                       ; preds = %entry
424   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 1)
425   %1 = extractvalue { i32, i1 } %0, 0
426   %2 = extractvalue { i32, i1 } %0, 1
427   br i1 %2, label %trap, label %cond.end
429 trap:                                             ; preds = %cond.false
430   tail call void @llvm.trap()
431   unreachable
433 cond.end:                                         ; preds = %cond.false, %entry
434   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
435   ret i32 %cond
438 define i32 @signed_add_rn1(i32 %x) {
439 ; CHECK-LABEL: @signed_add_rn1(
440 ; CHECK-NEXT:  entry:
441 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
442 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
443 ; CHECK:       cond.false:
444 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[X]], -1
445 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
446 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
447 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
448 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
449 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
450 ; CHECK:       trap:
451 ; CHECK-NEXT:    tail call void @llvm.trap()
452 ; CHECK-NEXT:    unreachable
453 ; CHECK:       cond.end:
454 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
455 ; CHECK-NEXT:    ret i32 [[COND]]
457 entry:
458   %cmp = icmp eq i32 %x, -2147483648
459   br i1 %cmp, label %cond.end, label %cond.false
461 cond.false:                                       ; preds = %entry
462   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 -1)
463   %1 = extractvalue { i32, i1 } %0, 0
464   %2 = extractvalue { i32, i1 } %0, 1
465   br i1 %2, label %trap, label %cond.end
467 trap:                                             ; preds = %cond.false
468   tail call void @llvm.trap()
469   unreachable
471 cond.end:                                         ; preds = %cond.false, %entry
472   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
473   ret i32 %cond
476 define i32 @signed_sub_rn1(i32 %x) {
477 ; CHECK-LABEL: @signed_sub_rn1(
478 ; CHECK-NEXT:  entry:
479 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
480 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
481 ; CHECK:       cond.false:
482 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nsw i32 [[X]], -1
483 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
484 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
485 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
486 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
487 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
488 ; CHECK:       trap:
489 ; CHECK-NEXT:    tail call void @llvm.trap()
490 ; CHECK-NEXT:    unreachable
491 ; CHECK:       cond.end:
492 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
493 ; CHECK-NEXT:    ret i32 [[COND]]
495 entry:
496   %cmp = icmp eq i32 %x, 2147483647
497   br i1 %cmp, label %cond.end, label %cond.false
499 cond.false:                                       ; preds = %entry
500   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 -1)
501   %1 = extractvalue { i32, i1 } %0, 0
502   %2 = extractvalue { i32, i1 } %0, 1
503   br i1 %2, label %trap, label %cond.end
505 trap:                                             ; preds = %cond.false
506   tail call void @llvm.trap()
507   unreachable
509 cond.end:                                         ; preds = %cond.false, %entry
510   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
511   ret i32 %cond
514 define i32 @unsigned_mul(i32 %x) {
515 ; CHECK-LABEL: @unsigned_mul(
516 ; CHECK-NEXT:  entry:
517 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 10000
518 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
519 ; CHECK:       cond.false:
520 ; CHECK-NEXT:    [[MULO1:%.*]] = mul nuw i32 [[X]], 100
521 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } undef, i32 [[MULO1]], 0
522 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } [[TMP0]], i1 false, 1
523 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
524 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
525 ; CHECK-NEXT:    br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
526 ; CHECK:       trap:
527 ; CHECK-NEXT:    tail call void @llvm.trap()
528 ; CHECK-NEXT:    unreachable
529 ; CHECK:       cond.end:
530 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[COND_FALSE]] ]
531 ; CHECK-NEXT:    ret i32 [[COND]]
533 entry:
534   %cmp = icmp ugt i32 %x, 10000
535   br i1 %cmp, label %cond.end, label %cond.false
537 cond.false:                                       ; preds = %entry
538   %mulo = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 100)
539   %res = extractvalue { i32, i1 } %mulo, 0
540   %ov = extractvalue { i32, i1 } %mulo, 1
541   br i1 %ov, label %trap, label %cond.end
543 trap:                                             ; preds = %cond.false
544   tail call void @llvm.trap()
545   unreachable
547 cond.end:                                         ; preds = %cond.false, %entry
548   %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
549   ret i32 %cond
552 define i32 @signed_mul(i32 %x) {
553 ; CHECK-LABEL: @signed_mul(
554 ; CHECK-NEXT:  entry:
555 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[X:%.*]], 10000
556 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], -10000
557 ; CHECK-NEXT:    [[CMP3:%.*]] = or i1 [[CMP1]], [[CMP2]]
558 ; CHECK-NEXT:    br i1 [[CMP3]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
559 ; CHECK:       cond.false:
560 ; CHECK-NEXT:    [[MULO1:%.*]] = mul nsw i32 [[X]], 100
561 ; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } undef, i32 [[MULO1]], 0
562 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } [[TMP0]], i1 false, 1
563 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
564 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
565 ; CHECK-NEXT:    br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
566 ; CHECK:       trap:
567 ; CHECK-NEXT:    tail call void @llvm.trap()
568 ; CHECK-NEXT:    unreachable
569 ; CHECK:       cond.end:
570 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[COND_FALSE]] ]
571 ; CHECK-NEXT:    ret i32 [[COND]]
573 entry:
574   %cmp1 = icmp sgt i32 %x, 10000
575   %cmp2 = icmp slt i32 %x, -10000
576   %cmp3 = or i1 %cmp1, %cmp2
577   br i1 %cmp3, label %cond.end, label %cond.false
579 cond.false:                                       ; preds = %entry
580   %mulo = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 100)
581   %res = extractvalue { i32, i1 } %mulo, 0
582   %ov = extractvalue { i32, i1 } %mulo, 1
583   br i1 %ov, label %trap, label %cond.end
585 trap:                                             ; preds = %cond.false
586   tail call void @llvm.trap()
587   unreachable
589 cond.end:                                         ; preds = %cond.false, %entry
590   %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
591   ret i32 %cond
594 declare i32 @bar(i32)
596 define void @unsigned_loop(i32 %i) {
597 ; CHECK-LABEL: @unsigned_loop(
598 ; CHECK-NEXT:  entry:
599 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[I:%.*]], 0
600 ; CHECK-NEXT:    br i1 [[CMP3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
601 ; CHECK:       while.body.preheader:
602 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
603 ; CHECK:       while.body:
604 ; CHECK-NEXT:    [[I_ADDR_04:%.*]] = phi i32 [ [[TMP4:%.*]], [[CONT:%.*]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
605 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @bar(i32 [[I_ADDR_04]])
606 ; CHECK-NEXT:    [[TMP0:%.*]] = sub nuw i32 [[I_ADDR_04]], 1
607 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
608 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
609 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
610 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT]]
611 ; CHECK:       trap:
612 ; CHECK-NEXT:    tail call void @llvm.trap()
613 ; CHECK-NEXT:    unreachable
614 ; CHECK:       cont:
615 ; CHECK-NEXT:    [[TMP4]] = extractvalue { i32, i1 } [[TMP2]], 0
616 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP4]], 0
617 ; CHECK-NEXT:    br i1 [[CMP]], label [[WHILE_END]], label [[WHILE_BODY]]
618 ; CHECK:       while.end:
619 ; CHECK-NEXT:    ret void
621 entry:
622   %cmp3 = icmp eq i32 %i, 0
623   br i1 %cmp3, label %while.end, label %while.body.preheader
625 while.body.preheader:                             ; preds = %entry
626   br label %while.body
628 while.body:                                       ; preds = %while.body.preheader, %cont
629   %i.addr.04 = phi i32 [ %2, %cont ], [ %i, %while.body.preheader ]
630   %call = tail call i32 @bar(i32 %i.addr.04)
631   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.addr.04, i32 1)
632   %1 = extractvalue { i32, i1 } %0, 1
633   br i1 %1, label %trap, label %cont
635 trap:                                             ; preds = %while.body
636   tail call void @llvm.trap()
637   unreachable
639 cont:                                             ; preds = %while.body
640   %2 = extractvalue { i32, i1 } %0, 0
641   %cmp = icmp eq i32 %2, 0
642   br i1 %cmp, label %while.end, label %while.body
644 while.end:                                        ; preds = %cont, %entry
645   ret void
648 define void @intrinsic_into_phi(i32 %n) {
649 ; CHECK-LABEL: @intrinsic_into_phi(
650 ; CHECK-NEXT:  entry:
651 ; CHECK-NEXT:    br label [[CONT:%.*]]
652 ; CHECK:       for.cond:
653 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[DOTLCSSA:%.*]], 1
654 ; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
655 ; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
656 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
657 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT]]
658 ; CHECK:       trap:
659 ; CHECK-NEXT:    tail call void @llvm.trap()
660 ; CHECK-NEXT:    unreachable
661 ; CHECK:       cont:
662 ; CHECK-NEXT:    [[TMP4:%.*]] = phi { i32, i1 } [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP2]], [[FOR_COND:%.*]] ]
663 ; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
664 ; CHECK-NEXT:    [[CALL9:%.*]] = tail call i32 @bar(i32 [[TMP5]])
665 ; CHECK-NEXT:    [[TOBOOL10:%.*]] = icmp eq i32 [[CALL9]], 0
666 ; CHECK-NEXT:    br i1 [[TOBOOL10]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
667 ; CHECK:       while.body.preheader:
668 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
669 ; CHECK:       while.cond:
670 ; CHECK-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP8:%.*]], 0
671 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @bar(i32 [[TMP6]])
672 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[CALL]], 0
673 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END]], label [[WHILE_BODY]]
674 ; CHECK:       while.body:
675 ; CHECK-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP6]], [[WHILE_COND:%.*]] ], [ [[TMP5]], [[WHILE_BODY_PREHEADER]] ]
676 ; CHECK-NEXT:    [[TMP8]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP7]], i32 1)
677 ; CHECK-NEXT:    [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
678 ; CHECK-NEXT:    br i1 [[TMP9]], label [[TRAP]], label [[WHILE_COND]]
679 ; CHECK:       while.end:
680 ; CHECK-NEXT:    [[DOTLCSSA]] = phi i32 [ [[TMP5]], [[CONT]] ], [ [[TMP6]], [[WHILE_COND]] ]
681 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[DOTLCSSA]], [[N:%.*]]
682 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND]], label [[CLEANUP2:%.*]]
683 ; CHECK:       cleanup2:
684 ; CHECK-NEXT:    ret void
686 entry:
687   br label %cont
689 for.cond:                                         ; preds = %while.end
690   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %.lcssa, i32 1)
691   %1 = extractvalue { i32, i1 } %0, 1
692   br i1 %1, label %trap, label %cont
694 trap:                                             ; preds = %for.cond, %while.body
695   tail call void @llvm.trap()
696   unreachable
698 cont:                                             ; preds = %entry, %for.cond
699   %2 = phi { i32, i1 } [ zeroinitializer, %entry ], [ %0, %for.cond ]
700   %3 = extractvalue { i32, i1 } %2, 0
701   %call9 = tail call i32 @bar(i32 %3)
702   %tobool10 = icmp eq i32 %call9, 0
703   br i1 %tobool10, label %while.end, label %while.body.preheader
705 while.body.preheader:                             ; preds = %cont
706   br label %while.body
708 while.cond:                                       ; preds = %while.body
709   %4 = extractvalue { i32, i1 } %6, 0
710   %call = tail call i32 @bar(i32 %4)
711   %tobool = icmp eq i32 %call, 0
712   br i1 %tobool, label %while.end, label %while.body
714 while.body:                                       ; preds = %while.body.preheader, %while.cond
715   %5 = phi i32 [ %4, %while.cond ], [ %3, %while.body.preheader ]
716   %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %5, i32 1)
717   %7 = extractvalue { i32, i1 } %6, 1
718   br i1 %7, label %trap, label %while.cond
720 while.end:                                        ; preds = %while.cond, %cont
721   %.lcssa = phi i32 [ %3, %cont ], [ %4, %while.cond ]
722   %cmp = icmp slt i32 %.lcssa, %n
723   br i1 %cmp, label %for.cond, label %cleanup2
725 cleanup2:                                         ; preds = %while.end
726   ret void
729 define { i8, i1 } @signed_mul_constant_folding() {
730 ; CHECK-LABEL: @signed_mul_constant_folding(
731 ; CHECK-NEXT:    ret { i8, i1 } { i8 2, i1 false }
733   %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 1, i8 2)
734   ret { i8, i1 } %mul
737 define { <2 x i32>, <2 x i1> } @uaddo_vec(<2 x i32> %a) {
738 ; CHECK-LABEL: @uaddo_vec(
739 ; 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>)
740 ; CHECK-NEXT:    ret { <2 x i32>, <2 x i1> } [[ADD]]
742   %add = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> %a, <2 x i32> <i32 1, i32 1>)
743   ret { <2 x i32>, <2 x i1> } %add
747 define i8 @uadd_sat_no_overflow(i8 %x) {
748 ; CHECK-LABEL: @uadd_sat_no_overflow(
749 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 100
750 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
751 ; CHECK:       trap:
752 ; CHECK-NEXT:    call void @llvm.trap()
753 ; CHECK-NEXT:    unreachable
754 ; CHECK:       cont:
755 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw i8 [[X]], 100
756 ; CHECK-NEXT:    ret i8 [[RES1]]
758   %cmp = icmp ugt i8 %x, 100
759   br i1 %cmp, label %trap, label %cont
761 trap:
762   call void @llvm.trap()
763   unreachable
765 cont:
766   %res = call i8 @llvm.uadd.sat.i8(i8 %x, i8 100)
767   ret i8 %res
770 define i8 @sadd_sat_no_overflow(i8 %x) {
771 ; CHECK-LABEL: @sadd_sat_no_overflow(
772 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 100
773 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
774 ; CHECK:       trap:
775 ; CHECK-NEXT:    call void @llvm.trap()
776 ; CHECK-NEXT:    unreachable
777 ; CHECK:       cont:
778 ; CHECK-NEXT:    [[RES1:%.*]] = add nsw i8 [[X]], 20
779 ; CHECK-NEXT:    ret i8 [[RES1]]
781   %cmp = icmp sgt i8 %x, 100
782   br i1 %cmp, label %trap, label %cont
784 trap:
785   call void @llvm.trap()
786   unreachable
788 cont:
789   %res = call i8 @llvm.sadd.sat.i8(i8 %x, i8 20)
790   ret i8 %res
793 define i8 @usub_sat_no_overflow(i8 %x) {
794 ; CHECK-LABEL: @usub_sat_no_overflow(
795 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], 100
796 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
797 ; CHECK:       trap:
798 ; CHECK-NEXT:    call void @llvm.trap()
799 ; CHECK-NEXT:    unreachable
800 ; CHECK:       cont:
801 ; CHECK-NEXT:    [[RES1:%.*]] = sub nuw i8 [[X]], 100
802 ; CHECK-NEXT:    ret i8 [[RES1]]
804   %cmp = icmp ult i8 %x, 100
805   br i1 %cmp, label %trap, label %cont
807 trap:
808   call void @llvm.trap()
809   unreachable
811 cont:
812   %res = call i8 @llvm.usub.sat.i8(i8 %x, i8 100)
813   ret i8 %res
816 define i8 @ssub_sat_no_overflow(i8 %x) {
817 ; CHECK-LABEL: @ssub_sat_no_overflow(
818 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -100
819 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRAP:%.*]], label [[CONT:%.*]]
820 ; CHECK:       trap:
821 ; CHECK-NEXT:    call void @llvm.trap()
822 ; CHECK-NEXT:    unreachable
823 ; CHECK:       cont:
824 ; CHECK-NEXT:    [[RES1:%.*]] = sub nsw i8 [[X]], 20
825 ; CHECK-NEXT:    ret i8 [[RES1]]
827   %cmp = icmp slt i8 %x, -100
828   br i1 %cmp, label %trap, label %cont
830 trap:
831   call void @llvm.trap()
832   unreachable
834 cont:
835   %res = call i8 @llvm.ssub.sat.i8(i8 %x, i8 20)
836   ret i8 %res
839 define <2 x i8> @uadd_sat_vec(<2 x i8> %a) {
840 ; CHECK-LABEL: @uadd_sat_vec(
841 ; CHECK-NEXT:    [[ADD:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 1, i8 1>)
842 ; CHECK-NEXT:    ret <2 x i8> [[ADD]]
844   %add = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 1, i8 1>)
845   ret <2 x i8> %add