xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/ne.ll (revision 7fb97bee9269f0d4239908ac8def70be696991c6)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4declare void @llvm.assume(i1)
5
6define i1 @test_eq_ne_0(i8 %a, i8 %b) {
7; CHECK-LABEL: @test_eq_ne_0(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 0
10; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
11; CHECK:       then:
12; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]]
13; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 false, true
14; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
15; CHECK-NEXT:    ret i1 [[RES_2]]
16; CHECK:       else:
17; CHECK-NEXT:    [[C_3:%.*]] = icmp ne i8 [[A]], 1
18; CHECK-NEXT:    [[C_4:%.*]] = icmp ne i8 [[A]], [[B]]
19; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 true, [[C_3]]
20; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]]
21; CHECK-NEXT:    ret i1 [[RES_4]]
22;
23entry:
24  %cmp = icmp eq i8 %a, 0
25  br i1 %cmp, label %then, label %else
26
27then:
28  %f.1 = icmp ne i8 %a, 0
29  %c.1 = icmp ne i8 %a, 1
30  %c.2 = icmp ne i8 %a, %b
31  %res.1 = xor i1 %f.1, %c.1
32  %res.2 = xor i1 %res.1, %c.2
33  ret i1 %res.2
34
35else:
36  %t.1 = icmp ne i8 %a, 0
37  %c.3 = icmp ne i8 %a, 1
38  %c.4 = icmp ne i8 %a, %b
39  %res.3 = xor i1 %t.1, %c.3
40  %res.4 = xor i1 %res.3, %c.4
41  ret i1 %res.4
42}
43
44define i1 @test_ne_eq_0(i8 %a, i8 %b) {
45; CHECK-LABEL: @test_ne_eq_0(
46; CHECK-NEXT:  entry:
47; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 0
48; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
49; CHECK:       then:
50; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[A]], 1
51; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[C_1]]
52; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]]
53; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
54; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i8 [[A]], [[B]]
55; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_3]]
56; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], false
57; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
58; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], true
59; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[A]], 1
60; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[C_5]]
61; CHECK-NEXT:    [[C_6:%.*]] = icmp sgt i8 [[A]], 0
62; CHECK-NEXT:    [[RES_8:%.*]] = xor i1 [[RES_7]], [[C_6]]
63; CHECK-NEXT:    ret i1 [[RES_8]]
64; CHECK:       else:
65; CHECK-NEXT:    [[RES_9:%.*]] = xor i1 false, true
66; CHECK-NEXT:    [[C_8:%.*]] = icmp ne i8 [[A]], [[B]]
67; CHECK-NEXT:    [[RES_10:%.*]] = xor i1 [[RES_9]], [[C_8]]
68; CHECK-NEXT:    [[C_9:%.*]] = icmp eq i8 [[A]], [[B]]
69; CHECK-NEXT:    [[RES_11:%.*]] = xor i1 [[RES_10]], [[C_9]]
70; CHECK-NEXT:    [[RES_12:%.*]] = xor i1 [[RES_11]], true
71; CHECK-NEXT:    [[RES_13:%.*]] = xor i1 [[RES_12]], false
72; CHECK-NEXT:    [[RES_14:%.*]] = xor i1 [[RES_13]], false
73; CHECK-NEXT:    [[RES_15:%.*]] = xor i1 [[RES_14]], false
74; CHECK-NEXT:    [[RES_16:%.*]] = xor i1 [[RES_15]], false
75; CHECK-NEXT:    ret i1 [[RES_16]]
76;
77entry:
78  %cmp = icmp ne i8 %a, 0
79  br i1 %cmp, label %then, label %else
80
81then:
82  %t.1 = icmp ne i8 %a, 0
83  %c.1 = icmp ne i8 %a, 1
84  %res.1 = xor i1 %t.1, %c.1
85
86  %c.2 = icmp ne i8 %a, %b
87  %res.2 = xor i1 %res.1, %c.2
88
89  %c.3 = icmp eq i8 %a, %b
90  %res.3 = xor i1 %res.2, %c.3
91
92  %c.4 = icmp eq i8 %a, 0
93  %res.4 = xor i1 %res.3, %c.4
94
95  %t.2 = icmp ugt i8 %a, 0
96  %res.5 = xor i1 %res.4, %t.2
97
98  %t.3 = icmp uge i8 %a, 1
99  %res.6 = xor i1 %res.5, %t.3
100
101  %c.5 = icmp ugt i8 %a, 1
102  %res.7 = xor i1 %res.6, %c.5
103
104  %c.6 = icmp sgt i8 %a, 0
105  %res.8 = xor i1 %res.7, %c.6
106
107  ret i1 %res.8
108
109else:
110  %f.1 = icmp ne i8 %a, 0
111  %c.7 = icmp ne i8 %a, 1
112  %res.9 = xor i1 %f.1, %c.7
113
114  %c.8 = icmp ne i8 %a, %b
115  %res.10 = xor i1 %res.9, %c.8
116
117  %c.9 = icmp eq i8 %a, %b
118  %res.11 = xor i1 %res.10, %c.9
119
120  %c.10 = icmp eq i8 %a, 0
121  %res.12 = xor i1 %res.11, %c.10
122
123  %f.2 = icmp ugt i8 %a, 0
124  %res.13 = xor i1 %res.12, %f.2
125
126  %f.3 = icmp uge i8 %a, 1
127  %res.14 = xor i1 %res.13, %f.3
128
129  %c.11 = icmp ugt i8 %a, 1
130  %res.15 = xor i1 %res.14, %c.11
131
132  %c.12 = icmp sgt i8 %a, 0
133  %res.16 = xor i1 %res.15, %c.12
134
135  ret i1 %res.16
136}
137
138define i1 @test_eq_ne_1(i8 %a, i8 %b) {
139; CHECK-LABEL: @test_eq_ne_1(
140; CHECK-NEXT:  entry:
141; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 1
142; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
143; CHECK:       then:
144; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]]
145; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, false
146; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
147; CHECK-NEXT:    ret i1 [[RES_2]]
148; CHECK:       else:
149; CHECK-NEXT:    [[T_1:%.*]] = icmp ne i8 [[A]], 0
150; CHECK-NEXT:    [[C_3:%.*]] = icmp ne i8 [[A]], 1
151; CHECK-NEXT:    [[C_4:%.*]] = icmp ne i8 [[A]], [[B]]
152; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[T_1]], [[C_3]]
153; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]]
154; CHECK-NEXT:    ret i1 [[RES_4]]
155;
156entry:
157  %cmp = icmp eq i8 %a, 1
158  br i1 %cmp, label %then, label %else
159
160then:
161  %f.1 = icmp ne i8 %a, 0
162  %c.1 = icmp ne i8 %a, 1
163  %c.2 = icmp ne i8 %a, %b
164  %res.1 = xor i1 %f.1, %c.1
165  %res.2 = xor i1 %res.1, %c.2
166  ret i1 %res.2
167
168else:
169  %t.1 = icmp ne i8 %a, 0
170  %c.3 = icmp ne i8 %a, 1
171  %c.4 = icmp ne i8 %a, %b
172  %res.3 = xor i1 %t.1, %c.3
173  %res.4 = xor i1 %res.3, %c.4
174  ret i1 %res.4
175}
176
177define i1 @test_ne_eq_1(i8 %a, i8 %b) {
178; CHECK-LABEL: @test_ne_eq_1(
179; CHECK-NEXT:  entry:
180; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 1
181; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
182; CHECK:       then:
183; CHECK-NEXT:    [[T_1:%.*]] = icmp ne i8 [[A]], 1
184; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[A]], 0
185; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[T_1]], [[C_1]]
186; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]]
187; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]]
188; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i8 [[A]], [[B]]
189; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_3]]
190; CHECK-NEXT:    [[C_4:%.*]] = icmp eq i8 [[A]], 0
191; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]]
192; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[A]], 0
193; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], [[C_5]]
194; CHECK-NEXT:    [[C_6:%.*]] = icmp uge i8 [[A]], 1
195; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[C_6]]
196; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i8 [[A]], 1
197; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[C_5]]
198; CHECK-NEXT:    [[C_8:%.*]] = icmp sgt i8 [[A]], 0
199; CHECK-NEXT:    [[RES_8:%.*]] = xor i1 [[RES_7]], [[C_6]]
200; CHECK-NEXT:    ret i1 [[RES_8]]
201; CHECK:       else:
202; CHECK-NEXT:    [[RES_9:%.*]] = xor i1 true, false
203; CHECK-NEXT:    [[C_10:%.*]] = icmp ne i8 [[A]], [[B]]
204; CHECK-NEXT:    [[RES_10:%.*]] = xor i1 [[RES_9]], [[C_10]]
205; CHECK-NEXT:    [[C_11:%.*]] = icmp eq i8 [[A]], [[B]]
206; CHECK-NEXT:    [[RES_11:%.*]] = xor i1 [[RES_10]], [[C_11]]
207; CHECK-NEXT:    [[RES_12:%.*]] = xor i1 [[RES_11]], false
208; CHECK-NEXT:    [[RES_13:%.*]] = xor i1 [[RES_12]], true
209; CHECK-NEXT:    [[RES_14:%.*]] = xor i1 [[RES_13]], true
210; CHECK-NEXT:    [[RES_15:%.*]] = xor i1 [[RES_14]], false
211; CHECK-NEXT:    [[RES_16:%.*]] = xor i1 [[RES_15]], true
212; CHECK-NEXT:    ret i1 [[RES_16]]
213;
214entry:
215  %cmp = icmp ne i8 %a, 1
216  br i1 %cmp, label %then, label %else
217
218then:
219  %t.1 = icmp ne i8 %a, 1
220  %c.1 = icmp ne i8 %a, 0
221  %res.1 = xor i1 %t.1, %c.1
222
223  %c.2 = icmp ne i8 %a, %b
224  %res.2 = xor i1 %res.1, %c.2
225
226  %c.3 = icmp eq i8 %a, %b
227  %res.3 = xor i1 %res.2, %c.3
228
229  %c.4 = icmp eq i8 %a, 0
230  %res.4 = xor i1 %res.3, %c.4
231
232  %c.5 = icmp ugt i8 %a, 0
233  %res.5 = xor i1 %res.4, %c.5
234
235  %c.6 = icmp uge i8 %a, 1
236  %res.6 = xor i1 %res.5, %c.6
237
238  %c.7 = icmp ugt i8 %a, 1
239  %res.7 = xor i1 %res.6, %c.5
240
241  %c.8 = icmp sgt i8 %a, 0
242  %res.8 = xor i1 %res.7, %c.6
243
244  ret i1 %res.8
245
246else:
247  %t.2 = icmp ne i8 %a, 0
248  %c.9 = icmp ne i8 %a, 1
249  %res.9 = xor i1 %t.2, %c.9
250
251  %c.10 = icmp ne i8 %a, %b
252  %res.10 = xor i1 %res.9, %c.10
253
254  %c.11 = icmp eq i8 %a, %b
255  %res.11 = xor i1 %res.10, %c.11
256
257  %f.1 = icmp eq i8 %a, 0
258  %res.12 = xor i1 %res.11, %f.1
259
260  %t.3 = icmp ugt i8 %a, 0
261  %res.13 = xor i1 %res.12, %t.3
262
263  %t.4 = icmp uge i8 %a, 1
264  %res.14 = xor i1 %res.13, %t.4
265
266  %f.2 = icmp ugt i8 %a, 1
267  %res.15 = xor i1 %res.14, %f.2
268
269  %c.12 = icmp sgt i8 %a, 0
270  %res.16 = xor i1 %res.15, %c.12
271
272  ret i1 %res.16
273}
274
275define i1 @assume_b_plus_1_ult_a(i64 %a, i64 %b) {
276; CHECK-LABEL: @assume_b_plus_1_ult_a(
277; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i64 [[B:%.*]], 1
278; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]]
279; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])
280; CHECK-NEXT:    ret i1 true
281;
282  %1 = add nuw i64 %b, 1
283  %2 = icmp ult i64 %1, %a
284  tail call void @llvm.assume(i1 %2)
285  %3 = icmp ne i64 %a, %b
286  ret i1 %3
287}
288
289define i1 @assume_a_gt_b_and_b_ge_c(i64 %a, i64 %b, i64 %c) {
290; CHECK-LABEL: @assume_a_gt_b_and_b_ge_c(
291; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i64 [[A:%.*]], [[B:%.*]]
292; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP1]])
293; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[B]], [[C:%.*]]
294; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])
295; CHECK-NEXT:    ret i1 true
296;
297  %1 = icmp ugt i64 %a, %b
298  tail call void @llvm.assume(i1 %1)
299  %2 = icmp uge i64 %b, %c
300  tail call void @llvm.assume(i1 %2)
301  %3 = icmp ne i64 %a, %c
302  ret i1 %3
303}
304
305define i1 @assume_a_ne_b_and_b_ne_c(i64 %a, i64 %b, i64 %c) {
306; CHECK-LABEL: @assume_a_ne_b_and_b_ne_c(
307; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
308; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP1]])
309; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B]], [[C:%.*]]
310; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])
311; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i64 [[A]], [[C]]
312; CHECK-NEXT:    ret i1 [[TMP3]]
313;
314  %1 = icmp ne i64 %a, %b
315  tail call void @llvm.assume(i1 %1)
316  %2 = icmp ne i64 %b, %c
317  tail call void @llvm.assume(i1 %2)
318  %3 = icmp ne i64 %a, %c
319  ret i1 %3
320}
321
322define i1 @assume_1a(i64 %a, i64 %b) {
323; CHECK-LABEL: @assume_1a(
324; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
325; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
326; CHECK-NEXT:    [[RET:%.*]] = icmp ugt i64 [[A]], [[B]]
327; CHECK-NEXT:    ret i1 [[RET]]
328;
329  %ne = icmp ne i64 %a, %b
330  tail call void @llvm.assume(i1 %ne)
331  %ret = icmp ugt i64 %a, %b
332  ret i1 %ret
333}
334
335define i1 @assume_1b(i64 %a, i64 %b) {
336; CHECK-LABEL: @assume_1b(
337; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
338; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
339; CHECK-NEXT:    [[RET:%.*]] = icmp uge i64 [[A]], [[B]]
340; CHECK-NEXT:    ret i1 [[RET]]
341;
342  %ne = icmp ne i64 %a, %b
343  tail call void @llvm.assume(i1 %ne)
344  %ret = icmp uge i64 %a, %b
345  ret i1 %ret
346}
347
348define i1 @assume_2a(i64 %a, i64 %b) {
349; CHECK-LABEL: @assume_2a(
350; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
351; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
352; CHECK-NEXT:    [[RET:%.*]] = icmp ult i64 [[A]], [[B]]
353; CHECK-NEXT:    ret i1 [[RET]]
354;
355  %ne = icmp ne i64 %a, %b
356  tail call void @llvm.assume(i1 %ne)
357  %ret = icmp ult i64 %a, %b
358  ret i1 %ret
359}
360
361define i1 @assume_2b(i64 %a, i64 %b) {
362; CHECK-LABEL: @assume_2b(
363; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
364; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
365; CHECK-NEXT:    [[RET:%.*]] = icmp ule i64 [[A]], [[B]]
366; CHECK-NEXT:    ret i1 [[RET]]
367;
368  %ne = icmp ne i64 %a, %b
369  tail call void @llvm.assume(i1 %ne)
370  %ret = icmp ule i64 %a, %b
371  ret i1 %ret
372}
373
374; TODO: extend to support signed comparisons
375define i1 @assume_3a(i64 %a, i64 %b) {
376; CHECK-LABEL: @assume_3a(
377; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
378; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
379; CHECK-NEXT:    [[RET:%.*]] = icmp sgt i64 [[A]], [[B]]
380; CHECK-NEXT:    ret i1 [[RET]]
381;
382  %ne = icmp ne i64 %a, %b
383  tail call void @llvm.assume(i1 %ne)
384  %ret = icmp sgt i64 %a, %b
385  ret i1 %ret
386}
387
388define i1 @assume_3b(i64 %a, i64 %b) {
389; CHECK-LABEL: @assume_3b(
390; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
391; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
392; CHECK-NEXT:    [[RET:%.*]] = icmp sge i64 [[A]], [[B]]
393; CHECK-NEXT:    ret i1 [[RET]]
394;
395  %ne = icmp ne i64 %a, %b
396  tail call void @llvm.assume(i1 %ne)
397  %ret = icmp sge i64 %a, %b
398  ret i1 %ret
399}
400
401define i1 @assume_4a(i64 %a, i64 %b) {
402; CHECK-LABEL: @assume_4a(
403; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
404; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
405; CHECK-NEXT:    [[RET:%.*]] = icmp slt i64 [[A]], [[B]]
406; CHECK-NEXT:    ret i1 [[RET]]
407;
408  %ne = icmp ne i64 %a, %b
409  tail call void @llvm.assume(i1 %ne)
410  %ret = icmp slt i64 %a, %b
411  ret i1 %ret
412}
413
414define i1 @assume_4b(i64 %a, i64 %b) {
415; CHECK-LABEL: @assume_4b(
416; CHECK-NEXT:    [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]]
417; CHECK-NEXT:    tail call void @llvm.assume(i1 [[NE]])
418; CHECK-NEXT:    [[RET:%.*]] = icmp sle i64 [[A]], [[B]]
419; CHECK-NEXT:    ret i1 [[RET]]
420;
421  %ne = icmp ne i64 %a, %b
422  tail call void @llvm.assume(i1 %ne)
423  %ret = icmp sle i64 %a, %b
424  ret i1 %ret
425}
426