Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / usub-with-overflow.ll
blob06bfd8269d97d7ebe5655f8f37ee4c87c2734f28
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8)
6 define i8 @usub_no_overflow_due_to_cmp_condition(i8 %a, i8 %b) {
7 ; CHECK-LABEL: @usub_no_overflow_due_to_cmp_condition(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]]
10 ; CHECK-NEXT:    br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
11 ; CHECK:       math:
12 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
13 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
14 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
15 ; CHECK:       exit.ok:
16 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
17 ; CHECK-NEXT:    ret i8 [[RES]]
18 ; CHECK:       exit.fail:
19 ; CHECK-NEXT:    ret i8 0
21 entry:
22   %c.1 = icmp uge i8 %b, %a
23   br i1 %c.1, label %math, label %exit.fail
25 math:
26   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
27   %status = extractvalue { i8, i1 } %op, 1
28   br i1 %status, label %exit.fail, label %exit.ok
30 exit.ok:
31   %res = extractvalue { i8, i1 } %op, 0
32   ret i8 %res
34 exit.fail:
35   ret i8 0
38 define i8 @usub_no_overflow_due_to_cmp_condition2(i8 %a, i8 %b) {
39 ; CHECK-LABEL: @usub_no_overflow_due_to_cmp_condition2(
40 ; CHECK-NEXT:  entry:
41 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]
42 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
43 ; CHECK:       math:
44 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
45 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
46 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
47 ; CHECK:       exit.ok:
48 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
49 ; CHECK-NEXT:    ret i8 [[RES]]
50 ; CHECK:       exit.fail:
51 ; CHECK-NEXT:    ret i8 0
53 entry:
54   %c.1 = icmp ule i8 %b, %a
55   br i1 %c.1, label %exit.fail, label %math
57 math:
58   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
59   %status = extractvalue { i8, i1 } %op, 1
60   br i1 %status, label %exit.fail, label %exit.ok
62 exit.ok:
63   %res = extractvalue { i8, i1 } %op, 0
64   ret i8 %res
66 exit.fail:
67   ret i8 0
70 declare void @use_res({ i8, i1 })
72 define i8 @sub_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) {
73 ; CHECK-LABEL: @sub_no_overflow_due_to_cmp_condition_result_used(
74 ; CHECK-NEXT:  entry:
75 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]
76 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
77 ; CHECK:       math:
78 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
79 ; CHECK-NEXT:    call void @use_res({ i8, i1 } [[OP]])
80 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
81 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
82 ; CHECK:       exit.ok:
83 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
84 ; CHECK-NEXT:    ret i8 [[RES]]
85 ; CHECK:       exit.fail:
86 ; CHECK-NEXT:    ret i8 0
88 entry:
89   %c.1 = icmp ule i8 %b, %a
90   br i1 %c.1, label %exit.fail, label %math
92 math:
93   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
94   call void @use_res({ i8, i1 } %op)
95   %status = extractvalue { i8, i1 } %op, 1
96   br i1 %status, label %exit.fail, label %exit.ok
98 exit.ok:
99   %res = extractvalue { i8, i1 } %op, 0
100   ret i8 %res
102 exit.fail:
103   ret i8 0
106 define i8 @usub_no_overflow_due_to_or_conds(i8 %a, i8 %b) {
107 ; CHECK-LABEL: @usub_no_overflow_due_to_or_conds(
108 ; CHECK-NEXT:  entry:
109 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]
110 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[A]], 0
111 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_2]], [[C_1]]
112 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
113 ; CHECK:       math:
114 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
115 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
116 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
117 ; CHECK:       exit.ok:
118 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
119 ; CHECK-NEXT:    ret i8 [[RES]]
120 ; CHECK:       exit.fail:
121 ; CHECK-NEXT:    ret i8 0
123 entry:
124   %c.1 = icmp ule i8 %b, %a
125   %c.2 = icmp ule i8 %a, 0
126   %or = or i1 %c.2, %c.1
127   br i1 %or, label %exit.fail, label %math
129 math:
130   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
131   %status = extractvalue { i8, i1 } %op, 1
132   br i1 %status, label %exit.fail, label %exit.ok
134 exit.ok:
135   %res = extractvalue { i8, i1 } %op, 0
136   ret i8 %res
138 exit.fail:
139   ret i8 0
142 define i8 @usub_no_overflow_due_to_or_conds_sub_result_not_used(i8 %a, i8 %b) {
143 ; CHECK-LABEL: @usub_no_overflow_due_to_or_conds_sub_result_not_used(
144 ; CHECK-NEXT:  entry:
145 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]
146 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i8 [[A]], 0
147 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_2]], [[C_1]]
148 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
149 ; CHECK:       math:
150 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
151 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
152 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
153 ; CHECK:       exit.ok:
154 ; CHECK-NEXT:    ret i8 20
155 ; CHECK:       exit.fail:
156 ; CHECK-NEXT:    ret i8 0
158 entry:
159   %c.1 = icmp ule i8 %b, %a
160   %c.2 = icmp ule i8 %a, 0
161   %or = or i1 %c.2, %c.1
162   br i1 %or, label %exit.fail, label %math
164 math:
165   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
166   %status = extractvalue { i8, i1 } %op, 1
167   br i1 %status, label %exit.fail, label %exit.ok
169 exit.ok:
170   ret i8 20
172 exit.fail:
173   ret i8 0
176 define i8 @usub_no_overflow_due_to_and_conds(i8 %a, i8 %b) {
177 ; CHECK-LABEL: @usub_no_overflow_due_to_and_conds(
178 ; CHECK-NEXT:  entry:
179 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]]
180 ; CHECK-NEXT:    [[C_2:%.*]] = icmp uge i8 [[A]], -1
181 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
182 ; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
183 ; CHECK:       math:
184 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
185 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
186 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
187 ; CHECK:       exit.ok:
188 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
189 ; CHECK-NEXT:    ret i8 [[RES]]
190 ; CHECK:       exit.fail:
191 ; CHECK-NEXT:    ret i8 0
193 entry:
194   %c.1 = icmp uge i8 %b, %a
195   %c.2 = icmp uge i8 %a, -1
196   %and = and i1 %c.2, %c.1
197   br i1 %and, label %math, label %exit.fail
199 math:
200   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
201   %status = extractvalue { i8, i1 } %op, 1
202   br i1 %status, label %exit.fail, label %exit.ok
204 exit.ok:
205   %res = extractvalue { i8, i1 } %op, 0
206   ret i8 %res
208 exit.fail:
209   ret i8 0
212 define i8 @usub_may_overflow1(i8 %a, i8 %b) {
213 ; CHECK-LABEL: @usub_may_overflow1(
214 ; CHECK-NEXT:  entry:
215 ; CHECK-NEXT:    br i1 true, label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
216 ; CHECK:       math:
217 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B:%.*]], i8 [[A:%.*]])
218 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
219 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
220 ; CHECK:       exit.ok:
221 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
222 ; CHECK-NEXT:    ret i8 [[RES]]
223 ; CHECK:       exit.fail:
224 ; CHECK-NEXT:    ret i8 0
226 entry:
227   %c.1 = icmp uge i8 %a, 0
228   br i1 %c.1, label %math, label %exit.fail
230 math:
231   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
232   %status = extractvalue { i8, i1 } %op, 1
233   br i1 %status, label %exit.fail, label %exit.ok
235 exit.ok:
236   %res = extractvalue { i8, i1 } %op, 0
237   ret i8 %res
239 exit.fail:
240   ret i8 0
244 define i8 @usub_may_overflow2(i8 %a, i8 %b) {
245 ; CHECK-LABEL: @usub_may_overflow2(
246 ; CHECK-NEXT:  entry:
247 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
248 ; CHECK-NEXT:    br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
249 ; CHECK:       math:
250 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
251 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
252 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
253 ; CHECK:       exit.ok:
254 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
255 ; CHECK-NEXT:    ret i8 [[RES]]
256 ; CHECK:       exit.fail:
257 ; CHECK-NEXT:    ret i8 0
259 entry:
260   %c.1 = icmp sge i8 %b, %a
261   br i1 %c.1, label %math, label %exit.fail
263 math:
264   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
265   %status = extractvalue { i8, i1 } %op, 1
266   br i1 %status, label %exit.fail, label %exit.ok
268 exit.ok:
269   %res = extractvalue { i8, i1 } %op, 0
270   ret i8 %res
272 exit.fail:
273   ret i8 0
276 define i8 @usub_may_overflow3(i8 %a, i8 %b) {
277 ; CHECK-LABEL: @usub_may_overflow3(
278 ; CHECK-NEXT:  entry:
279 ; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[B:%.*]], [[A:%.*]]
280 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
281 ; CHECK:       math:
282 ; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
283 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
284 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
285 ; CHECK:       exit.ok:
286 ; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
287 ; CHECK-NEXT:    ret i8 [[RES]]
288 ; CHECK:       exit.fail:
289 ; CHECK-NEXT:    ret i8 0
291 entry:
292   %c.1 = icmp slt i8 %b, %a
293   br i1 %c.1, label %exit.fail, label %math
294 math:
295   %op = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %b, i8 %a)
296   %status = extractvalue { i8, i1 } %op, 1
297   br i1 %status, label %exit.fail, label %exit.ok
299 exit.ok:
300   %res = extractvalue { i8, i1 } %op, 0
301   ret i8 %res
303 exit.fail:
304   ret i8 0