• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -correlated-propagation < %s | FileCheck %s
3
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
9
10declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
11
12declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
13
14declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
15
16declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
17
18declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
19
20declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
21
22declare { i8, i1 } @llvm.umul.with.overflow.i8(i8, i8)
23
24declare { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32>, <2 x i32>)
25
26declare i8 @llvm.uadd.sat.i8(i8, i8)
27declare i8 @llvm.sadd.sat.i8(i8, i8)
28declare i8 @llvm.usub.sat.i8(i8, i8)
29declare i8 @llvm.ssub.sat.i8(i8, i8)
30declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>)
31
32declare void @llvm.trap()
33
34
35define 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]]
72;
73entry:
74  %cmp = icmp sgt i32 %y, 0
75  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
76
77land.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
81
82trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
83  tail call void @llvm.trap()
84  unreachable
85
86cont:                                             ; 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
90
91lor.lhs.false:                                    ; preds = %entry
92  %cmp2 = icmp slt i32 %y, 0
93  br i1 %cmp2, label %land.lhs.true3, label %cond.false
94
95land.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
99
100cont4:                                            ; 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
104
105cond.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
110
111cond.end:                                         ; preds = %cond.false, %cont, %cont4
112  %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
113  ret i32 %cond
114}
115
116define 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]]
138;
139entry:
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
143
144trap:                                             ; preds = %cond.false, %entry
145  tail call void @llvm.trap()
146  unreachable
147
148cont:                                             ; 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
152
153cond.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
158
159cond.end:                                         ; preds = %cond.false, %cont
160  %cond = phi i32 [ 0, %cont ], [ %4, %cond.false ]
161  ret i32 %cond
162}
163
164define 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]]
201;
202entry:
203  %cmp = icmp slt i32 %y, 0
204  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
205
206land.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
210
211trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
212  tail call void @llvm.trap()
213  unreachable
214
215cont:                                             ; 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
219
220lor.lhs.false:                                    ; preds = %entry
221  %cmp2 = icmp eq i32 %y, 0
222  br i1 %cmp2, label %cond.false, label %land.lhs.true3
223
224land.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
228
229cont4:                                            ; 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
233
234cond.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
239
240cond.end:                                         ; preds = %cond.false, %cont, %cont4
241  %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
242  ret i32 %cond
243}
244
245define 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]]
261;
262entry:
263  %cmp = icmp ult i32 %x, %y
264  br i1 %cmp, label %cond.end, label %cond.false
265
266cond.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
271
272trap:                                             ; preds = %cond.false
273  tail call void @llvm.trap()
274  unreachable
275
276cond.end:                                         ; preds = %cond.false, %entry
277  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
278  ret i32 %cond
279}
280
281define 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]]
298;
299entry:
300  %cmp = icmp eq i32 %x, 2147483647
301  br i1 %cmp, label %cond.end, label %cond.false
302
303cond.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
308
309trap:                                             ; preds = %cond.false
310  tail call void @llvm.trap()
311  unreachable
312
313cond.end:                                         ; preds = %cond.false, %entry
314  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
315  ret i32 %cond
316}
317
318define 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]]
335;
336entry:
337  %cmp = icmp eq i32 %x, -1
338  br i1 %cmp, label %cond.end, label %cond.false
339
340cond.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
345
346trap:                                             ; preds = %cond.false
347  tail call void @llvm.trap()
348  unreachable
349
350cond.end:                                         ; preds = %cond.false, %entry
351  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
352  ret i32 %cond
353}
354
355define 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]]
372;
373entry:
374  %cmp = icmp eq i32 %x, -2147483648
375  br i1 %cmp, label %cond.end, label %cond.false
376
377cond.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
382
383trap:                                             ; preds = %cond.false
384  tail call void @llvm.trap()
385  unreachable
386
387cond.end:                                         ; preds = %cond.false, %entry
388  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
389  ret i32 %cond
390}
391
392define 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]]
409;
410entry:
411  %cmp = icmp eq i32 %x, 0
412  br i1 %cmp, label %cond.end, label %cond.false
413
414cond.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
419
420trap:                                             ; preds = %cond.false
421  tail call void @llvm.trap()
422  unreachable
423
424cond.end:                                         ; preds = %cond.false, %entry
425  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
426  ret i32 %cond
427}
428
429define 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]]
446;
447entry:
448  %cmp = icmp eq i32 %x, -2147483648
449  br i1 %cmp, label %cond.end, label %cond.false
450
451cond.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
456
457trap:                                             ; preds = %cond.false
458  tail call void @llvm.trap()
459  unreachable
460
461cond.end:                                         ; preds = %cond.false, %entry
462  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
463  ret i32 %cond
464}
465
466define 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]]
483;
484entry:
485  %cmp = icmp eq i32 %x, 2147483647
486  br i1 %cmp, label %cond.end, label %cond.false
487
488cond.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
493
494trap:                                             ; preds = %cond.false
495  tail call void @llvm.trap()
496  unreachable
497
498cond.end:                                         ; preds = %cond.false, %entry
499  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
500  ret i32 %cond
501}
502
503define 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]]
520;
521entry:
522  %cmp = icmp ugt i32 %x, 10000
523  br i1 %cmp, label %cond.end, label %cond.false
524
525cond.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
530
531trap:                                             ; preds = %cond.false
532  tail call void @llvm.trap()
533  unreachable
534
535cond.end:                                         ; preds = %cond.false, %entry
536  %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
537  ret i32 %cond
538}
539
540define 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]]
559;
560entry:
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
565
566cond.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
571
572trap:                                             ; preds = %cond.false
573  tail call void @llvm.trap()
574  unreachable
575
576cond.end:                                         ; preds = %cond.false, %entry
577  %cond = phi i32 [ 0, %entry ], [ %res, %cond.false ]
578  ret i32 %cond
579}
580
581declare i32 @bar(i32)
582
583define 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
606;
607entry:
608  %cmp3 = icmp eq i32 %i, 0
609  br i1 %cmp3, label %while.end, label %while.body.preheader
610
611while.body.preheader:                             ; preds = %entry
612  br label %while.body
613
614while.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
620
621trap:                                             ; preds = %while.body
622  tail call void @llvm.trap()
623  unreachable
624
625cont:                                             ; 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
629
630while.end:                                        ; preds = %cont, %entry
631  ret void
632}
633
634define 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
670;
671entry:
672  br label %cont
673
674for.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
678
679trap:                                             ; preds = %for.cond, %while.body
680  tail call void @llvm.trap()
681  unreachable
682
683cont:                                             ; 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
689
690while.body.preheader:                             ; preds = %cont
691  br label %while.body
692
693while.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
698
699while.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
704
705while.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
709
710cleanup2:                                         ; preds = %while.end
711  ret void
712}
713
714define { i8, i1 } @signed_mul_constant_folding() {
715; CHECK-LABEL: @signed_mul_constant_folding(
716; CHECK-NEXT:    ret { i8, i1 } { i8 2, i1 false }
717;
718  %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 1, i8 2)
719  ret { i8, i1 } %mul
720}
721
722define { <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]]
726;
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
729}
730
731
732define 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]]
742;
743  %cmp = icmp ugt i8 %x, 100
744  br i1 %cmp, label %trap, label %cont
745
746trap:
747  call void @llvm.trap()
748  unreachable
749
750cont:
751  %res = call i8 @llvm.uadd.sat.i8(i8 %x, i8 100)
752  ret i8 %res
753}
754
755define 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]]
765;
766  %cmp = icmp ugt i8 %x, 27
767  br i1 %cmp, label %trap, label %cont
768
769trap:
770  call void @llvm.trap()
771  unreachable
772
773cont:
774  %res = call i8 @llvm.uadd.sat.i8(i8 %x, i8 100)
775  ret i8 %res
776}
777
778define 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]]
788;
789  %cmp = icmp sgt i8 %x, 100
790  br i1 %cmp, label %trap, label %cont
791
792trap:
793  call void @llvm.trap()
794  unreachable
795
796cont:
797  %res = call i8 @llvm.sadd.sat.i8(i8 %x, i8 20)
798  ret i8 %res
799}
800
801define 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]]
811;
812  %cmp = icmp ugt i8 %x, 107
813  br i1 %cmp, label %trap, label %cont
814
815trap:
816  call void @llvm.trap()
817  unreachable
818
819cont:
820  %res = call i8 @llvm.sadd.sat.i8(i8 %x, i8 20)
821  ret i8 %res
822}
823
824define 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]]
834;
835  %cmp = icmp ult i8 %x, 100
836  br i1 %cmp, label %trap, label %cont
837
838trap:
839  call void @llvm.trap()
840  unreachable
841
842cont:
843  %res = call i8 @llvm.usub.sat.i8(i8 %x, i8 100)
844  ret i8 %res
845}
846
847define 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]]
857;
858  %cmp = icmp ult i8 %x, 228
859  br i1 %cmp, label %trap, label %cont
860
861trap:
862  call void @llvm.trap()
863  unreachable
864
865cont:
866  %res = call i8 @llvm.usub.sat.i8(i8 %x, i8 100)
867  ret i8 %res
868}
869
870define 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]]
880;
881  %cmp = icmp slt i8 %x, -100
882  br i1 %cmp, label %trap, label %cont
883
884trap:
885  call void @llvm.trap()
886  unreachable
887
888cont:
889  %res = call i8 @llvm.ssub.sat.i8(i8 %x, i8 20)
890  ret i8 %res
891}
892
893define 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]]
903;
904  %cmp = icmp ult i8 %x, 148
905  br i1 %cmp, label %trap, label %cont
906
907trap:
908  call void @llvm.trap()
909  unreachable
910
911cont:
912  %res = call i8 @llvm.ssub.sat.i8(i8 %x, i8 20)
913  ret i8 %res
914}
915
916define <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]]
920;
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
923}
924
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.
928
929define 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 [[OUT]]
944; CHECK:       out:
945; CHECK-NEXT:    ret i1 true
946;
947entry:
948  %x.offset = add i32 %x, 9
949  %cmp1 = icmp ult i32 %x.offset, 19
950  br i1 %cmp1, label %cont1, label %out
951
952cont1:
953  %y.offset = add i32 %y, 9
954  %cmp2 = icmp ult i32 %y.offset, 19
955  br i1 %cmp2, label %cont2, label %out
956
957cont2:
958  ; x = [-9,10), y = [-9,10)
959  %res = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
960  %add = extractvalue { i32, i1 } %res, 0
961  ; add = [-18,19)
962  %cmp3 = icmp slt i32 %add, 19
963  br label %out
964
965out:
966  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
967  ret i1 %ret
968}
969
970
971define i1 @uadd_and_cmp(i32 %x, i32 %y) #0 {
972; CHECK-LABEL: @uadd_and_cmp(
973; CHECK-NEXT:  entry:
974; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
975; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
976; CHECK:       cont1:
977; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
978; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
979; CHECK:       cont2:
980; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw i32 [[X]], [[Y]]
981; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
982; CHECK-NEXT:    [[ADD:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
983; CHECK-NEXT:    br label [[OUT]]
984; CHECK:       out:
985; CHECK-NEXT:    ret i1 true
986;
987entry:
988  %cmp1 = icmp ult i32 %x, 10
989  br i1 %cmp1, label %cont1, label %out
990
991cont1:
992  %cmp2 = icmp ult i32 %y, 10
993  br i1 %cmp2, label %cont2, label %out
994
995cont2:
996  %res = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
997  %add = extractvalue { i32, i1 } %res, 0
998  %cmp3 = icmp ult i32 %add, 19
999  br label %out
1000
1001out:
1002  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
1003  ret i1 %ret
1004}
1005
1006define i1 @ssub_and_cmp(i32 %x, i32 %y) #0 {
1007; CHECK-LABEL: @ssub_and_cmp(
1008; CHECK-NEXT:  entry:
1009; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
1010; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1011; CHECK:       cont1:
1012; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
1013; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1014; CHECK:       cont2:
1015; CHECK-NEXT:    [[OFFSET:%.*]] = add nuw nsw i32 [[X]], 9
1016; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i32 [[OFFSET]], [[Y]]
1017; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1018; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1019; CHECK-NEXT:    br label [[OUT]]
1020; CHECK:       out:
1021; CHECK-NEXT:    ret i1 true
1022;
1023entry:
1024  %cmp1 = icmp ult i32 %x, 10
1025  br i1 %cmp1, label %cont1, label %out
1026
1027cont1:
1028  %cmp2 = icmp ult i32 %y, 10
1029  br i1 %cmp2, label %cont2, label %out
1030
1031cont2:
1032  %offset = add i32 %x, 9
1033  ; x = [0,10), y = [0,10), offset = [9,19)
1034  %res = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %offset, i32 %y)
1035  %sub = extractvalue { i32, i1 } %res, 0
1036  %cmp3 = icmp ult i32 %sub, 19
1037  br label %out
1038
1039out:
1040  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
1041  ret i1 %ret
1042}
1043
1044define i1 @usub_and_cmp(i32 %x, i32 %y) #0 {
1045; CHECK-LABEL: @usub_and_cmp(
1046; CHECK-NEXT:  entry:
1047; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
1048; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1049; CHECK:       cont1:
1050; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
1051; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1052; CHECK:       cont2:
1053; CHECK-NEXT:    [[OFFSET:%.*]] = add nuw nsw i32 [[X]], 9
1054; CHECK-NEXT:    [[RES1:%.*]] = sub nuw nsw i32 [[OFFSET]], [[Y]]
1055; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1056; CHECK-NEXT:    [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1057; CHECK-NEXT:    br label [[OUT]]
1058; CHECK:       out:
1059; CHECK-NEXT:    ret i1 true
1060;
1061entry:
1062  %cmp1 = icmp ult i32 %x, 10
1063  br i1 %cmp1, label %cont1, label %out
1064
1065cont1:
1066  %cmp2 = icmp ult i32 %y, 10
1067  br i1 %cmp2, label %cont2, label %out
1068
1069cont2:
1070  %offset = add i32 %x, 9
1071  ; x = [0,10), y = [0,10), offset = [9,19)
1072  %res = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %offset, i32 %y)
1073  %sub = extractvalue { i32, i1 } %res, 0
1074  %cmp3 = icmp ult i32 %sub, 19
1075  br label %out
1076
1077out:
1078  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
1079  ret i1 %ret
1080}
1081
1082define i1 @smul_and_cmp(i32 %x, i32 %y) #0 {
1083; CHECK-LABEL: @smul_and_cmp(
1084; CHECK-NEXT:  entry:
1085; CHECK-NEXT:    [[X_OFFSET:%.*]] = add i32 [[X:%.*]], 9
1086; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X_OFFSET]], 19
1087; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1088; CHECK:       cont1:
1089; CHECK-NEXT:    [[Y_OFFSET:%.*]] = add i32 [[Y:%.*]], 9
1090; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y_OFFSET]], 19
1091; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1092; CHECK:       cont2:
1093; CHECK-NEXT:    [[RES1:%.*]] = mul nsw i32 [[X]], [[Y]]
1094; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1095; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1096; CHECK-NEXT:    br label [[OUT]]
1097; CHECK:       out:
1098; CHECK-NEXT:    ret i1 true
1099;
1100entry:
1101  %x.offset = add i32 %x, 9
1102  %cmp1 = icmp ult i32 %x.offset, 19
1103  br i1 %cmp1, label %cont1, label %out
1104
1105cont1:
1106  %y.offset = add i32 %y, 9
1107  %cmp2 = icmp ult i32 %y.offset, 19
1108  br i1 %cmp2, label %cont2, label %out
1109
1110cont2:
1111  ; x = [-9,10), y = [-9,10)
1112  %res = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 %y)
1113  %mul = extractvalue { i32, i1 } %res, 0
1114  %cmp3 = icmp sle i32 %mul, 81
1115  %cmp4 = icmp sge i32 %mul, -81
1116  %cmp5 = and i1 %cmp3, %cmp4
1117  br label %out
1118
1119out:
1120  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp5, %cont2 ]
1121  ret i1 %ret
1122}
1123
1124define i1 @umul_and_cmp(i32 %x, i32 %y) #0 {
1125; CHECK-LABEL: @umul_and_cmp(
1126; CHECK-NEXT:  entry:
1127; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 100
1128; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
1129; CHECK:       cont1:
1130; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 100
1131; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
1132; CHECK:       cont2:
1133; CHECK-NEXT:    [[RES1:%.*]] = mul nuw nsw i32 [[X]], [[Y]]
1134; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[RES1]], 0
1135; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
1136; CHECK-NEXT:    br label [[OUT]]
1137; CHECK:       out:
1138; CHECK-NEXT:    ret i1 true
1139;
1140entry:
1141  %cmp1 = icmp ult i32 %x, 100
1142  br i1 %cmp1, label %cont1, label %out
1143
1144cont1:
1145  %cmp2 = icmp ult i32 %y, 100
1146  br i1 %cmp2, label %cont2, label %out
1147
1148cont2:
1149  %res = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
1150  %mul = extractvalue { i32, i1 } %res, 0
1151  %cmp3 = icmp ule i32 %mul, 9801
1152  br label %out
1153
1154out:
1155  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
1156  ret i1 %ret
1157}
1158