1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -correlated-propagation < %s | FileCheck %s
4 declare void @llvm.trap()
5 declare {i8, i1} @llvm.uadd.with.overflow(i8, i8)
6 declare {i8, i1} @llvm.sadd.with.overflow(i8, i8)
7 declare {i8, i1} @llvm.usub.with.overflow(i8, i8)
8 declare {i8, i1} @llvm.ssub.with.overflow(i8, i8)
9 declare {i8, i1} @llvm.umul.with.overflow(i8, i8)
10 declare {i8, i1} @llvm.smul.with.overflow(i8, i8)
12 define i1 @uadd_ov_false(i8 %x, i8* %px, i1* %pc) {
13 ; CHECK-LABEL: @uadd_ov_false(
14 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X:%.*]], i8 100)
15 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
16 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
17 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
18 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
20 ; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[X]], -102
21 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
22 ; CHECK-NEXT: ret i1 false
24 ; CHECK-NEXT: call void @llvm.trap()
25 ; CHECK-NEXT: unreachable
27 %val_ov = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 100)
28 %val = extractvalue {i8, i1} %val_ov, 0
29 store i8 %val, i8* %px
30 %ov = extractvalue {i8, i1} %val_ov, 1
31 br i1 %ov, label %trap, label %no_overflow
34 %c1 = icmp ugt i8 %x, 154
36 %c2 = icmp ugt i8 %x, 155
40 call void @llvm.trap()
44 define i1 @uadd_ov_true(i8 %x, i8* %px, i1* %pc) {
45 ; CHECK-LABEL: @uadd_ov_true(
46 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X:%.*]], i8 100)
47 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
48 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
49 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
50 ; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
52 ; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[X]], -100
53 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
54 ; CHECK-NEXT: ret i1 true
56 ; CHECK-NEXT: call void @llvm.trap()
57 ; CHECK-NEXT: unreachable
59 %val_ov = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 100)
60 %val = extractvalue {i8, i1} %val_ov, 0
61 store i8 %val, i8* %px
62 %ov = extractvalue {i8, i1} %val_ov, 1
63 br i1 %ov, label %overflow, label %trap
66 %c1 = icmp ugt i8 %x, 156
68 %c2 = icmp ugt i8 %x, 155
72 call void @llvm.trap()
76 define i1 @sadd_ov_false(i8 %x, i8* %px, i1* %pc) {
77 ; CHECK-LABEL: @sadd_ov_false(
78 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 100)
79 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
80 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
81 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
82 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
84 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[X]], 26
85 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
86 ; CHECK-NEXT: ret i1 false
88 ; CHECK-NEXT: call void @llvm.trap()
89 ; CHECK-NEXT: unreachable
91 %val_ov = call {i8, i1} @llvm.sadd.with.overflow(i8 %x, i8 100)
92 %val = extractvalue {i8, i1} %val_ov, 0
93 store i8 %val, i8* %px
94 %ov = extractvalue {i8, i1} %val_ov, 1
95 br i1 %ov, label %trap, label %no_overflow
98 %c1 = icmp sgt i8 %x, 26
100 %c2 = icmp sgt i8 %x, 27
104 call void @llvm.trap()
108 define i1 @sadd_ov_true(i8 %x, i8* %px, i1* %pc) {
109 ; CHECK-LABEL: @sadd_ov_true(
110 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 100)
111 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
112 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
113 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
114 ; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
116 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[X]], 28
117 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
118 ; CHECK-NEXT: ret i1 true
120 ; CHECK-NEXT: call void @llvm.trap()
121 ; CHECK-NEXT: unreachable
123 %val_ov = call {i8, i1} @llvm.sadd.with.overflow(i8 %x, i8 100)
124 %val = extractvalue {i8, i1} %val_ov, 0
125 store i8 %val, i8* %px
126 %ov = extractvalue {i8, i1} %val_ov, 1
127 br i1 %ov, label %overflow, label %trap
130 %c1 = icmp sgt i8 %x, 28
131 store i1 %c1, i1* %pc
132 %c2 = icmp sgt i8 %x, 27
136 call void @llvm.trap()
140 define i1 @usub_ov_false(i8 %x, i8* %px, i1* %pc) {
141 ; CHECK-LABEL: @usub_ov_false(
142 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 100)
143 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
144 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
145 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
146 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
147 ; CHECK: no_overflow:
148 ; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[X]], 101
149 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
150 ; CHECK-NEXT: ret i1 false
152 ; CHECK-NEXT: call void @llvm.trap()
153 ; CHECK-NEXT: unreachable
155 %val_ov = call {i8, i1} @llvm.usub.with.overflow(i8 %x, i8 100)
156 %val = extractvalue {i8, i1} %val_ov, 0
157 store i8 %val, i8* %px
158 %ov = extractvalue {i8, i1} %val_ov, 1
159 br i1 %ov, label %trap, label %no_overflow
162 %c1 = icmp ult i8 %x, 101
163 store i1 %c1, i1* %pc
164 %c2 = icmp ult i8 %x, 100
168 call void @llvm.trap()
172 define i1 @usub_ov_true(i8 %x, i8* %px, i1* %pc) {
173 ; CHECK-LABEL: @usub_ov_true(
174 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 100)
175 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
176 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
177 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
178 ; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
180 ; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[X]], 99
181 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
182 ; CHECK-NEXT: ret i1 true
184 ; CHECK-NEXT: call void @llvm.trap()
185 ; CHECK-NEXT: unreachable
187 %val_ov = call {i8, i1} @llvm.usub.with.overflow(i8 %x, i8 100)
188 %val = extractvalue {i8, i1} %val_ov, 0
189 store i8 %val, i8* %px
190 %ov = extractvalue {i8, i1} %val_ov, 1
191 br i1 %ov, label %overflow, label %trap
194 %c1 = icmp ult i8 %x, 99
195 store i1 %c1, i1* %pc
196 %c2 = icmp ult i8 %x, 100
200 call void @llvm.trap()
204 define i1 @ssub_ov_false(i8 %x, i8* %px, i1* %pc) {
205 ; CHECK-LABEL: @ssub_ov_false(
206 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 100)
207 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
208 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
209 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
210 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
211 ; CHECK: no_overflow:
212 ; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[X]], -27
213 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
214 ; CHECK-NEXT: ret i1 false
216 ; CHECK-NEXT: call void @llvm.trap()
217 ; CHECK-NEXT: unreachable
219 %val_ov = call {i8, i1} @llvm.ssub.with.overflow(i8 %x, i8 100)
220 %val = extractvalue {i8, i1} %val_ov, 0
221 store i8 %val, i8* %px
222 %ov = extractvalue {i8, i1} %val_ov, 1
223 br i1 %ov, label %trap, label %no_overflow
226 %c1 = icmp slt i8 %x, -27
227 store i1 %c1, i1* %pc
228 %c2 = icmp slt i8 %x, -28
232 call void @llvm.trap()
236 define i1 @ssub_ov_true(i8 %x, i8* %px, i1* %pc) {
237 ; CHECK-LABEL: @ssub_ov_true(
238 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 100)
239 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
240 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
241 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
242 ; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
244 ; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[X]], -29
245 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
246 ; CHECK-NEXT: ret i1 true
248 ; CHECK-NEXT: call void @llvm.trap()
249 ; CHECK-NEXT: unreachable
251 %val_ov = call {i8, i1} @llvm.ssub.with.overflow(i8 %x, i8 100)
252 %val = extractvalue {i8, i1} %val_ov, 0
253 store i8 %val, i8* %px
254 %ov = extractvalue {i8, i1} %val_ov, 1
255 br i1 %ov, label %overflow, label %trap
258 %c1 = icmp slt i8 %x, -29
259 store i1 %c1, i1* %pc
260 %c2 = icmp slt i8 %x, -28
264 call void @llvm.trap()
268 define i1 @umul_ov_false(i8 %x, i8* %px, i1* %pc) {
269 ; CHECK-LABEL: @umul_ov_false(
270 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X:%.*]], i8 10)
271 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
272 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
273 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
274 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
275 ; CHECK: no_overflow:
276 ; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[X]], 24
277 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
278 ; CHECK-NEXT: ret i1 false
280 ; CHECK-NEXT: call void @llvm.trap()
281 ; CHECK-NEXT: unreachable
283 %val_ov = call {i8, i1} @llvm.umul.with.overflow(i8 %x, i8 10)
284 %val = extractvalue {i8, i1} %val_ov, 0
285 store i8 %val, i8* %px
286 %ov = extractvalue {i8, i1} %val_ov, 1
287 br i1 %ov, label %trap, label %no_overflow
290 %c1 = icmp ugt i8 %x, 24
291 store i1 %c1, i1* %pc
292 %c2 = icmp ugt i8 %x, 25
296 call void @llvm.trap()
300 define i1 @umul_ov_true(i8 %x, i8* %px, i1* %pc) {
301 ; CHECK-LABEL: @umul_ov_true(
302 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X:%.*]], i8 10)
303 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
304 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
305 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
306 ; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
308 ; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[X]], 26
309 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
310 ; CHECK-NEXT: ret i1 true
312 ; CHECK-NEXT: call void @llvm.trap()
313 ; CHECK-NEXT: unreachable
315 %val_ov = call {i8, i1} @llvm.umul.with.overflow(i8 %x, i8 10)
316 %val = extractvalue {i8, i1} %val_ov, 0
317 store i8 %val, i8* %px
318 %ov = extractvalue {i8, i1} %val_ov, 1
319 br i1 %ov, label %overflow, label %trap
322 %c1 = icmp ugt i8 %x, 26
323 store i1 %c1, i1* %pc
324 %c2 = icmp ugt i8 %x, 25
328 call void @llvm.trap()
332 ; Signed mul is constrained from both sides.
333 define i1 @smul_ov_false_bound1(i8 %x, i8* %px, i1* %pc) {
334 ; CHECK-LABEL: @smul_ov_false_bound1(
335 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)
336 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
337 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
338 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
339 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
340 ; CHECK: no_overflow:
341 ; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[X]], -11
342 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
343 ; CHECK-NEXT: ret i1 false
345 ; CHECK-NEXT: call void @llvm.trap()
346 ; CHECK-NEXT: unreachable
348 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)
349 %val = extractvalue {i8, i1} %val_ov, 0
350 store i8 %val, i8* %px
351 %ov = extractvalue {i8, i1} %val_ov, 1
352 br i1 %ov, label %trap, label %no_overflow
355 %c1 = icmp slt i8 %x, -11
356 store i1 %c1, i1* %pc
357 %c2 = icmp slt i8 %x, -12
361 call void @llvm.trap()
365 define i1 @smul_ov_false_bound2(i8 %x, i8* %px, i1* %pc) {
366 ; CHECK-LABEL: @smul_ov_false_bound2(
367 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)
368 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
369 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
370 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
371 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
372 ; CHECK: no_overflow:
373 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[X]], 11
374 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
375 ; CHECK-NEXT: ret i1 false
377 ; CHECK-NEXT: call void @llvm.trap()
378 ; CHECK-NEXT: unreachable
380 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)
381 %val = extractvalue {i8, i1} %val_ov, 0
382 store i8 %val, i8* %px
383 %ov = extractvalue {i8, i1} %val_ov, 1
384 br i1 %ov, label %trap, label %no_overflow
387 %c1 = icmp sgt i8 %x, 11
388 store i1 %c1, i1* %pc
389 %c2 = icmp sgt i8 %x, 12
393 call void @llvm.trap()
397 ; Can't use slt/sgt to test for a hole in the range, check equality instead.
398 define i1 @smul_ov_true_bound1(i8 %x, i8* %px, i1* %pc) {
399 ; CHECK-LABEL: @smul_ov_true_bound1(
400 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)
401 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
402 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
403 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
404 ; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
406 ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], -13
407 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
408 ; CHECK-NEXT: ret i1 false
410 ; CHECK-NEXT: call void @llvm.trap()
411 ; CHECK-NEXT: unreachable
413 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)
414 %val = extractvalue {i8, i1} %val_ov, 0
415 store i8 %val, i8* %px
416 %ov = extractvalue {i8, i1} %val_ov, 1
417 br i1 %ov, label %overflow, label %trap
420 %c1 = icmp eq i8 %x, -13
421 store i1 %c1, i1* %pc
422 %c2 = icmp eq i8 %x, -12
426 call void @llvm.trap()
430 define i1 @smul_ov_true_bound2(i8 %x, i8* %px, i1* %pc) {
431 ; CHECK-LABEL: @smul_ov_true_bound2(
432 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)
433 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
434 ; CHECK-NEXT: store i8 [[VAL]], i8* [[PX:%.*]]
435 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
436 ; CHECK-NEXT: br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
438 ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], 13
439 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
440 ; CHECK-NEXT: ret i1 false
442 ; CHECK-NEXT: call void @llvm.trap()
443 ; CHECK-NEXT: unreachable
445 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)
446 %val = extractvalue {i8, i1} %val_ov, 0
447 store i8 %val, i8* %px
448 %ov = extractvalue {i8, i1} %val_ov, 1
449 br i1 %ov, label %overflow, label %trap
452 %c1 = icmp eq i8 %x, 13
453 store i1 %c1, i1* %pc
454 %c2 = icmp eq i8 %x, 12
458 call void @llvm.trap()
462 define i1 @uadd_val(i8 %x, i1* %pc) {
463 ; CHECK-LABEL: @uadd_val(
464 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X:%.*]], i8 100)
465 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
466 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
467 ; CHECK: no_overflow:
468 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
469 ; CHECK-NEXT: br label [[SPLIT:%.*]]
471 ; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[VAL]], 100
472 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
473 ; CHECK-NEXT: ret i1 true
475 ; CHECK-NEXT: call void @llvm.trap()
476 ; CHECK-NEXT: unreachable
478 %val_ov = call {i8, i1} @llvm.uadd.with.overflow(i8 %x, i8 100)
479 %ov = extractvalue {i8, i1} %val_ov, 1
480 br i1 %ov, label %trap, label %no_overflow
483 %val = extractvalue {i8, i1} %val_ov, 0
487 %c1 = icmp ugt i8 %val, 100
488 store i1 %c1, i1* %pc
489 %c2 = icmp uge i8 %val, 100
493 call void @llvm.trap()
497 define i1 @sadd_val(i8 %x, i1* %pc) {
498 ; CHECK-LABEL: @sadd_val(
499 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 100)
500 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
501 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
502 ; CHECK: no_overflow:
503 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
504 ; CHECK-NEXT: br label [[SPLIT:%.*]]
506 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[VAL]], -28
507 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
508 ; CHECK-NEXT: ret i1 true
510 ; CHECK-NEXT: call void @llvm.trap()
511 ; CHECK-NEXT: unreachable
513 %val_ov = call {i8, i1} @llvm.sadd.with.overflow(i8 %x, i8 100)
514 %ov = extractvalue {i8, i1} %val_ov, 1
515 br i1 %ov, label %trap, label %no_overflow
518 %val = extractvalue {i8, i1} %val_ov, 0
522 %c1 = icmp sgt i8 %val, -28
523 store i1 %c1, i1* %pc
524 %c2 = icmp sge i8 %val, -28
528 call void @llvm.trap()
532 define i1 @usub_val(i8 %x, i1* %pc) {
533 ; CHECK-LABEL: @usub_val(
534 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 100)
535 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
536 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
537 ; CHECK: no_overflow:
538 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
539 ; CHECK-NEXT: br label [[SPLIT:%.*]]
541 ; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[VAL]], -101
542 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
543 ; CHECK-NEXT: ret i1 true
545 ; CHECK-NEXT: call void @llvm.trap()
546 ; CHECK-NEXT: unreachable
548 %val_ov = call {i8, i1} @llvm.usub.with.overflow(i8 %x, i8 100)
549 %ov = extractvalue {i8, i1} %val_ov, 1
550 br i1 %ov, label %trap, label %no_overflow
553 %val = extractvalue {i8, i1} %val_ov, 0
557 %c1 = icmp ult i8 %val, 155
558 store i1 %c1, i1* %pc
559 %c2 = icmp ule i8 %val, 155
563 call void @llvm.trap()
567 define i1 @ssub_val(i8 %x, i1* %pc) {
568 ; CHECK-LABEL: @ssub_val(
569 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 100)
570 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
571 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
572 ; CHECK: no_overflow:
573 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
574 ; CHECK-NEXT: br label [[SPLIT:%.*]]
576 ; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[VAL]], 27
577 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
578 ; CHECK-NEXT: ret i1 true
580 ; CHECK-NEXT: call void @llvm.trap()
581 ; CHECK-NEXT: unreachable
583 %val_ov = call {i8, i1} @llvm.ssub.with.overflow(i8 %x, i8 100)
584 %ov = extractvalue {i8, i1} %val_ov, 1
585 br i1 %ov, label %trap, label %no_overflow
588 %val = extractvalue {i8, i1} %val_ov, 0
592 %c1 = icmp slt i8 %val, 27
593 store i1 %c1, i1* %pc
594 %c2 = icmp sle i8 %val, 27
598 call void @llvm.trap()
602 define i1 @umul_val(i8 %x, i1* %pc) {
603 ; CHECK-LABEL: @umul_val(
604 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X:%.*]], i8 10)
605 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
606 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
607 ; CHECK: no_overflow:
608 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
609 ; CHECK-NEXT: br label [[SPLIT:%.*]]
611 ; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[VAL]], -6
612 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
613 ; CHECK-NEXT: ret i1 true
615 ; CHECK-NEXT: call void @llvm.trap()
616 ; CHECK-NEXT: unreachable
618 %val_ov = call {i8, i1} @llvm.umul.with.overflow(i8 %x, i8 10)
619 %ov = extractvalue {i8, i1} %val_ov, 1
620 br i1 %ov, label %trap, label %no_overflow
623 %val = extractvalue {i8, i1} %val_ov, 0
627 %c1 = icmp ult i8 %val, 250
628 store i1 %c1, i1* %pc
629 %c2 = icmp ule i8 %val, 250
633 call void @llvm.trap()
637 define i1 @smul_val_bound1(i8 %x, i1* %pc) {
638 ; CHECK-LABEL: @smul_val_bound1(
639 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)
640 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
641 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
642 ; CHECK: no_overflow:
643 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
644 ; CHECK-NEXT: br label [[SPLIT:%.*]]
646 ; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[VAL]], 120
647 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
648 ; CHECK-NEXT: ret i1 true
650 ; CHECK-NEXT: call void @llvm.trap()
651 ; CHECK-NEXT: unreachable
653 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)
654 %ov = extractvalue {i8, i1} %val_ov, 1
655 br i1 %ov, label %trap, label %no_overflow
658 %val = extractvalue {i8, i1} %val_ov, 0
662 %c1 = icmp slt i8 %val, 120
663 store i1 %c1, i1* %pc
664 %c2 = icmp sle i8 %val, 120
668 call void @llvm.trap()
672 define i1 @smul_val_bound2(i8 %x, i1* %pc) {
673 ; CHECK-LABEL: @smul_val_bound2(
674 ; CHECK-NEXT: [[VAL_OV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 10)
675 ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
676 ; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[NO_OVERFLOW:%.*]]
677 ; CHECK: no_overflow:
678 ; CHECK-NEXT: [[VAL:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 0
679 ; CHECK-NEXT: br label [[SPLIT:%.*]]
681 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[VAL]], -120
682 ; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
683 ; CHECK-NEXT: ret i1 true
685 ; CHECK-NEXT: call void @llvm.trap()
686 ; CHECK-NEXT: unreachable
688 %val_ov = call {i8, i1} @llvm.smul.with.overflow(i8 %x, i8 10)
689 %ov = extractvalue {i8, i1} %val_ov, 1
690 br i1 %ov, label %trap, label %no_overflow
693 %val = extractvalue {i8, i1} %val_ov, 0
697 %c1 = icmp sgt i8 %val, -120
698 store i1 %c1, i1* %pc
699 %c2 = icmp sge i8 %val, -120
703 call void @llvm.trap()