Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / transfer-unsigned-facts-to-signed.ll
blob23953f18f07d5fe488c17a23e6c4b6946a6a563c
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 define i1 @idx_known_positive_via_len_1(i8 %len, i8 %idx) {
5 ; CHECK-LABEL: @idx_known_positive_via_len_1(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[LEN_POS:%.*]] = icmp sge i8 [[LEN:%.*]], 0
8 ; CHECK-NEXT:    [[IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
9 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[LEN_POS]], [[IDX_ULT_LEN]]
10 ; CHECK-NEXT:    br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
11 ; CHECK:       then.1:
12 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, true
13 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[IDX]], 1
14 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
15 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], true
16 ; CHECK-NEXT:    ret i1 [[R_3]]
17 ; CHECK:       else:
18 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i8 [[IDX]], 0
19 ; CHECK-NEXT:    ret i1 [[C_3]]
21 entry:
22   %len.pos = icmp sge i8 %len, 0
23   %idx.ult.len  = icmp ult i8 %idx, %len
24   %and.1 = and i1 %len.pos, %idx.ult.len
25   br i1 %and.1, label %then.1, label %else
27 then.1:
28   %t.1 = icmp ult i8 %idx, %len
29   %t.2 = icmp sge i8 %idx, 0
30   %r.1 = xor i1 %t.1, %t.2
32   %c.1 = icmp sge i8 %idx, 1
33   %r.2 = xor i1 %r.1, %c.1
35   %c.2 = icmp sge i8 %len, 1
36   %r.3 = xor i1 %r.2, %c.2
37   ret i1 %r.3
39 else:
40   %c.3 = icmp sge i8 %idx, 0
41   ret i1 %c.3
44 ; Like @idx_known_positive_via_len_1, but with a different order of known facts.
45 define i1 @idx_known_positive_via_len_2(i8 %len, i8 %idx) {
46 ; CHECK-LABEL: @idx_known_positive_via_len_2(
47 ; CHECK-NEXT:  entry:
48 ; CHECK-NEXT:    [[IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN:%.*]]
49 ; CHECK-NEXT:    [[LEN_POS:%.*]] = icmp sge i8 [[LEN]], 0
50 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[IDX_ULT_LEN]], [[LEN_POS]]
51 ; CHECK-NEXT:    br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
52 ; CHECK:       then.1:
53 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, true
54 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[IDX]], 1
55 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
56 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], true
57 ; CHECK-NEXT:    ret i1 [[R_3]]
58 ; CHECK:       else:
59 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i8 [[IDX]], 0
60 ; CHECK-NEXT:    ret i1 [[C_3]]
62 entry:
63   %idx.ult.len  = icmp ult i8 %idx, %len
64   %len.pos = icmp sge i8 %len, 0
65   %and.1 = and i1 %idx.ult.len, %len.pos
66   br i1 %and.1, label %then.1, label %else
68 then.1:
69   %t.1 = icmp ult i8 %idx, %len
70   %t.2 = icmp sge i8 %idx, 0
71   %r.1 = xor i1 %t.1, %t.2
73   %c.1 = icmp sge i8 %idx, 1
74   %r.2 = xor i1 %r.1, %c.1
76   %c.2 = icmp sge i8 %len, 1
77   %r.3 = xor i1 %r.2, %c.2
78   ret i1 %r.3
80 else:
81   %c.3 = icmp sge i8 %idx, 0
82   ret i1 %c.3
86 ; %len >=u 0 is not enough to determine idx >=s 0.
87 define i1 @idx_not_known_positive_via_len_uge(i8 %len, i8 %idx) {
88 ; CHECK-LABEL: @idx_not_known_positive_via_len_uge(
89 ; CHECK-NEXT:  entry:
90 ; CHECK-NEXT:    [[IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN:%.*]]
91 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 true, [[IDX_ULT_LEN]]
92 ; CHECK-NEXT:    br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
93 ; CHECK:       then.1:
94 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[IDX]], 0
95 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, [[C_2]]
96 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i8 [[IDX]], 1
97 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
98 ; CHECK-NEXT:    [[C_4:%.*]] = icmp sge i8 [[LEN]], 1
99 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
100 ; CHECK-NEXT:    ret i1 [[R_3]]
101 ; CHECK:       else:
102 ; CHECK-NEXT:    [[C_5:%.*]] = icmp sge i8 [[IDX]], 0
103 ; CHECK-NEXT:    ret i1 [[C_5]]
105 entry:
106   %len.pos = icmp uge i8 %len, 0
107   %idx.ult.len  = icmp ult i8 %idx, %len
108   %and.1 = and i1 %len.pos, %idx.ult.len
109   br i1 %and.1, label %then.1, label %else
111 then.1:
112   %c.1 = icmp ult i8 %idx, %len
113   %c.2 = icmp sge i8 %idx, 0
114   %r.1 = xor i1 %c.1, %c.2
116   %c.3 = icmp sge i8 %idx, 1
117   %r.2 = xor i1 %r.1, %c.3
119   %c.4 = icmp sge i8 %len, 1
120   %r.3 = xor i1 %r.2, %c.4
121   ret i1 %r.3
123 else:
124   %c.5 = icmp sge i8 %idx, 0
125   ret i1 %c.5
128 ; There's no information about %len which could be used to determine %len >=s 0.
129 define i1 @idx_not_known_positive_via_len(i8 %len, i8 %idx) {
130 ; CHECK-LABEL: @idx_not_known_positive_via_len(
131 ; CHECK-NEXT:  entry:
132 ; CHECK-NEXT:    [[IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN:%.*]]
133 ; CHECK-NEXT:    br i1 [[IDX_ULT_LEN]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
134 ; CHECK:       then.1:
135 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[IDX]], 0
136 ; CHECK-NEXT:    [[R_1:%.*]] = xor i1 true, [[C_2]]
137 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i8 [[IDX]], 1
138 ; CHECK-NEXT:    [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
139 ; CHECK-NEXT:    [[C_4:%.*]] = icmp sge i8 [[LEN]], 1
140 ; CHECK-NEXT:    [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
141 ; CHECK-NEXT:    ret i1 [[R_3]]
142 ; CHECK:       else:
143 ; CHECK-NEXT:    [[C_5:%.*]] = icmp sge i8 [[IDX]], 0
144 ; CHECK-NEXT:    ret i1 [[C_5]]
146 entry:
147   %idx.ult.len  = icmp ult i8 %idx, %len
148   br i1 %idx.ult.len, label %then.1, label %else
150 then.1:
151   %c.1 = icmp ult i8 %idx, %len
152   %c.2 = icmp sge i8 %idx, 0
153   %r.1 = xor i1 %c.1, %c.2
155   %c.3 = icmp sge i8 %idx, 1
156   %r.2 = xor i1 %r.1, %c.3
158   %c.4 = icmp sge i8 %len, 1
159   %r.3 = xor i1 %r.2, %c.4
160   ret i1 %r.3
162 else:
163   %c.5 = icmp sge i8 %idx, 0
164   ret i1 %c.5
167 define i1 @ult_signed_pos_constant(i8 %a) {
168 ; CHECK-LABEL: @ult_signed_pos_constant(
169 ; CHECK-NEXT:    [[A_ULT_4:%.*]] = icmp ult i8 [[A:%.*]], 4
170 ; CHECK-NEXT:    br i1 [[A_ULT_4]], label [[THEN:%.*]], label [[ELSE:%.*]]
171 ; CHECK:       then:
172 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
173 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], true
174 ; CHECK-NEXT:    ret i1 [[RES_2]]
175 ; CHECK:       else:
176 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
177 ; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[A]], 4
178 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[C_2]], [[C_3]]
179 ; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[A]], 5
180 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]]
181 ; CHECK-NEXT:    ret i1 [[RES_4]]
183   %a.ult.4 = icmp ult i8 %a, 4
184   br i1 %a.ult.4, label %then, label %else
186 then:
187   %t.0 = icmp sge i8 %a, 0
188   %t.1 = icmp slt i8 %a, 4
189   %res.1 = xor i1 %t.0, %t.1
191   %c.0 = icmp slt i8 %a, 5
192   %res.2 = xor i1 %res.1, %c.0
193   ret i1 %res.2
195 else:
196   %c.2 = icmp sge i8 %a, 0
197   %c.3 = icmp slt i8 %a, 4
198   %res.3 = xor i1 %c.2, %c.3
200   %c.4 = icmp slt i8 %a, 5
201   %res.4 = xor i1 %res.3, %c.4
203   ret i1 %res.4
206 define i1 @ult_signed_neg_constant(i8 %a) {
207 ; CHECK-LABEL: @ult_signed_neg_constant(
208 ; CHECK-NEXT:    [[A_ULT_4:%.*]] = icmp ult i8 [[A:%.*]], -2
209 ; CHECK-NEXT:    br i1 [[A_ULT_4]], label [[THEN:%.*]], label [[ELSE:%.*]]
210 ; CHECK:       then:
211 ; CHECK-NEXT:    [[C_0:%.*]] = icmp sge i8 [[A]], 0
212 ; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[A]], -2
213 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_0]], [[C_1]]
214 ; CHECK-NEXT:    ret i1 [[RES_1]]
215 ; CHECK:       else:
216 ; CHECK-NEXT:    ret i1 false
218   %a.ult.4 = icmp ult i8 %a, -2
219   br i1 %a.ult.4, label %then, label %else
221 then:
222   %c.0 = icmp sge i8 %a, 0
223   %c.1 = icmp slt i8 %a, -2
224   %res.1 = xor i1 %c.0, %c.1
225   ret i1 %res.1
227 else:
228   ret i1 0
231 define i1 @ule_signed_pos_constant_1(i8 %a, i8 %b) {
232 ; CHECK-LABEL: @ule_signed_pos_constant_1(
233 ; CHECK-NEXT:    [[B_NON_NEG:%.*]] = icmp sge i8 [[B:%.*]], 0
234 ; CHECK-NEXT:    call void @llvm.assume(i1 [[B_NON_NEG]])
235 ; CHECK-NEXT:    [[A_ULE_B:%.*]] = icmp ule i8 [[A:%.*]], [[B]]
236 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_ULE_B]])
237 ; CHECK-NEXT:    [[SLT_TEST:%.*]] = icmp slt i8 [[A]], [[B]]
238 ; CHECK-NEXT:    [[RESULT_XOR:%.*]] = xor i1 true, [[SLT_TEST]]
239 ; CHECK-NEXT:    ret i1 [[RESULT_XOR]]
241   %b_non_neg = icmp sge i8 %b, 0
242   call void @llvm.assume(i1 %b_non_neg)
243   %a_ule_b = icmp ule i8 %a, %b
244   call void @llvm.assume(i1 %a_ule_b)
246   %sle_test = icmp sle i8 %a, %b
247   %slt_test = icmp slt i8 %a, %b
248   %result_xor = xor i1 %sle_test, %slt_test
250   ret i1 %result_xor
253 define i1 @ule_signed_pos_constant_2(i8 %a) {
254 ; CHECK-LABEL: @ule_signed_pos_constant_2(
255 ; CHECK-NEXT:    [[A_ULT_4:%.*]] = icmp ule i8 [[A:%.*]], 4
256 ; CHECK-NEXT:    br i1 [[A_ULT_4]], label [[THEN:%.*]], label [[ELSE:%.*]]
257 ; CHECK:       then:
258 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
259 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], true
260 ; CHECK-NEXT:    ret i1 [[RES_2]]
261 ; CHECK:       else:
262 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
263 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sle i8 [[A]], 4
264 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[C_2]], [[C_3]]
265 ; CHECK-NEXT:    [[C_4:%.*]] = icmp sle i8 [[A]], 5
266 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]]
267 ; CHECK-NEXT:    ret i1 [[RES_4]]
269   %a.ult.4 = icmp ule i8 %a, 4
270   br i1 %a.ult.4, label %then, label %else
272 then:
273   %t.0 = icmp sge i8 %a, 0
274   %t.1 = icmp sle i8 %a, 4
275   %res.1 = xor i1 %t.0, %t.1
277   %c.0 = icmp sle i8 %a, 5
278   %res.2 = xor i1 %res.1, %c.0
279   ret i1 %res.2
281 else:
282   %c.2 = icmp sge i8 %a, 0
283   %c.3 = icmp sle i8 %a, 4
284   %res.3 = xor i1 %c.2, %c.3
286   %c.4 = icmp sle i8 %a, 5
287   %res.4 = xor i1 %res.3, %c.4
289   ret i1 %res.4
292 define i1 @uge_assumed_positive_values(i8 %a, i8 %b) {
293 ; CHECK-LABEL: @uge_assumed_positive_values(
294 ; CHECK-NEXT:    [[A_NON_NEG:%.*]] = icmp sge i8 [[A:%.*]], 0
295 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NON_NEG]])
296 ; CHECK-NEXT:    [[A_UGT_B:%.*]] = icmp uge i8 [[A]], [[B:%.*]]
297 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_UGT_B]])
298 ; CHECK-NEXT:    ret i1 true
300   %a_non_neg = icmp sge i8 %a, 0
301   call void @llvm.assume(i1 %a_non_neg)
302   %a_ugt_b = icmp uge i8 %a, %b
303   call void @llvm.assume(i1 %a_ugt_b)
305   %result = icmp sge i8 %a, %b
307   ret i1 %result
310 define i1 @ugt_assumed_positive_values(i8 %a, i8 %b) {
311 ; CHECK-LABEL: @ugt_assumed_positive_values(
312 ; CHECK-NEXT:    [[A_NON_NEG:%.*]] = icmp sge i8 [[A:%.*]], 0
313 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NON_NEG]])
314 ; CHECK-NEXT:    [[A_UGT_B:%.*]] = icmp ugt i8 [[A]], [[B:%.*]]
315 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_UGT_B]])
316 ; CHECK-NEXT:    ret i1 true
318   %a_non_neg = icmp sge i8 %a, 0
319   call void @llvm.assume(i1 %a_non_neg)
320   %a_ugt_b = icmp ugt i8 %a, %b
321   call void @llvm.assume(i1 %a_ugt_b)
323   %result = icmp sgt i8 %a, %b
325   ret i1 %result
328 declare void @llvm.assume(i1)