xref: /llvm-project/llvm/test/Transforms/InstCombine/implies.ll (revision a105877646d68e48cdeeeadd9d1e075dc3c5d68d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i1 @or_implies_sle(i8 %x, i8 %y, i1 %other) {
5; CHECK-LABEL: @or_implies_sle(
6; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], 23
7; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[OR]], [[Y:%.*]]
8; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
9; CHECK:       T:
10; CHECK-NEXT:    ret i1 true
11; CHECK:       F:
12; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
13;
14  %or = or i8 %x, 23
15  %cond = icmp sle i8 %or, %y
16  br i1 %cond, label %T, label %F
17T:
18  %r = icmp sle i8 %x, %y
19  ret i1 %r
20F:
21  ret i1 %other
22}
23
24define i1 @or_implies_sle_fail(i8 %x, i8 %y, i1 %other) {
25; CHECK-LABEL: @or_implies_sle_fail(
26; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], -34
27; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[OR]], [[Y:%.*]]
28; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
29; CHECK:       T:
30; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[X]], [[Y]]
31; CHECK-NEXT:    ret i1 [[R]]
32; CHECK:       F:
33; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
34;
35  %or = or i8 %x, -34
36  %cond = icmp sle i8 %or, %y
37  br i1 %cond, label %T, label %F
38T:
39  %r = icmp sle i8 %x, %y
40  ret i1 %r
41F:
42  ret i1 %other
43}
44
45define i1 @or_distjoint_implies_ule(i8 %x, i8 %y, i1 %other) {
46; CHECK-LABEL: @or_distjoint_implies_ule(
47; CHECK-NEXT:    [[X2:%.*]] = or disjoint i8 [[X:%.*]], 24
48; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ugt i8 [[X2]], [[Y:%.*]]
49; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
50; CHECK:       T:
51; CHECK-NEXT:    ret i1 true
52; CHECK:       F:
53; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
54;
55  %x1 = or disjoint i8 %x, 23
56  %x2 = or disjoint i8 %x, 24
57
58  %cond = icmp ule i8 %x2, %y
59  br i1 %cond, label %T, label %F
60T:
61  %r = icmp ule i8 %x1, %y
62  ret i1 %r
63F:
64  ret i1 %other
65}
66
67define i1 @or_distjoint_implies_ule_fail(i8 %x, i8 %y, i1 %other) {
68; CHECK-LABEL: @or_distjoint_implies_ule_fail(
69; CHECK-NEXT:    [[X2:%.*]] = or disjoint i8 [[X:%.*]], 24
70; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ugt i8 [[X2]], [[Y:%.*]]
71; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
72; CHECK:       T:
73; CHECK-NEXT:    [[X1:%.*]] = or disjoint i8 [[X]], 28
74; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[X1]], [[Y]]
75; CHECK-NEXT:    ret i1 [[R]]
76; CHECK:       F:
77; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
78;
79  %x1 = or disjoint i8 %x, 28
80  %x2 = or disjoint i8 %x, 24
81
82  %cond = icmp ule i8 %x2, %y
83  br i1 %cond, label %T, label %F
84T:
85  %r = icmp ule i8 %x1, %y
86  ret i1 %r
87F:
88  ret i1 %other
89}
90
91define i1 @or_prove_distjoin_implies_ule(i8 %xx, i8 %y, i1 %other) {
92; CHECK-LABEL: @or_prove_distjoin_implies_ule(
93; CHECK-NEXT:    [[X:%.*]] = and i8 [[XX:%.*]], -16
94; CHECK-NEXT:    [[X2:%.*]] = or disjoint i8 [[X]], 10
95; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ugt i8 [[X2]], [[Y:%.*]]
96; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
97; CHECK:       T:
98; CHECK-NEXT:    ret i1 true
99; CHECK:       F:
100; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
101;
102  %x = and i8 %xx, -16
103  %x1 = or i8 %x, 7
104  %x2 = or i8 %x, 10
105
106  %cond = icmp ule i8 %x2, %y
107  br i1 %cond, label %T, label %F
108T:
109  %r = icmp ule i8 %x1, %y
110  ret i1 %r
111F:
112  ret i1 %other
113}
114
115define i1 @src_or_distjoint_implies_sle(i8 %x, i8 %y, i1 %other) {
116; CHECK-LABEL: @src_or_distjoint_implies_sle(
117; CHECK-NEXT:    [[X2:%.*]] = or disjoint i8 [[X:%.*]], 24
118; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[X2]], [[Y:%.*]]
119; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
120; CHECK:       T:
121; CHECK-NEXT:    ret i1 true
122; CHECK:       F:
123; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
124;
125  %x1 = or disjoint i8 %x, 23
126  %x2 = or disjoint i8 %x, 24
127
128  %cond = icmp sle i8 %x2, %y
129  br i1 %cond, label %T, label %F
130T:
131  %r = icmp sle i8 %x1, %y
132  ret i1 %r
133F:
134  ret i1 %other
135}
136
137define i1 @src_or_distjoint_implies_sle_fail(i8 %x, i8 %y, i1 %other) {
138; CHECK-LABEL: @src_or_distjoint_implies_sle_fail(
139; CHECK-NEXT:    [[X2:%.*]] = or disjoint i8 [[X:%.*]], 24
140; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[Y:%.*]], [[X2]]
141; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
142; CHECK:       T:
143; CHECK-NEXT:    [[X1:%.*]] = or disjoint i8 [[X]], 23
144; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[X1]], [[Y]]
145; CHECK-NEXT:    ret i1 [[R]]
146; CHECK:       F:
147; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
148;
149  %x1 = or disjoint i8 %x, 23
150  %x2 = or disjoint i8 %x, 24
151
152  %cond = icmp sle i8 %y, %x2
153  br i1 %cond, label %T, label %F
154T:
155  %r = icmp sle i8 %x1, %y
156  ret i1 %r
157F:
158  ret i1 %other
159}
160
161define i1 @src_addnsw_implies_sle(i8 %x, i8 %y, i1 %other) {
162; CHECK-LABEL: @src_addnsw_implies_sle(
163; CHECK-NEXT:    [[X2:%.*]] = add nsw i8 [[X:%.*]], 24
164; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[X2]], [[Y:%.*]]
165; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
166; CHECK:       T:
167; CHECK-NEXT:    ret i1 true
168; CHECK:       F:
169; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
170;
171  %x1 = add nsw i8 %x, 23
172  %x2 = add nsw i8 %x, 24
173
174  %cond = icmp sle i8 %x2, %y
175  br i1 %cond, label %T, label %F
176T:
177  %r = icmp sle i8 %x1, %y
178  ret i1 %r
179F:
180  ret i1 %other
181}
182
183define i1 @src_addnsw_implies_sle_fail(i8 %x, i8 %y, i1 %other) {
184; CHECK-LABEL: @src_addnsw_implies_sle_fail(
185; CHECK-NEXT:    [[X2:%.*]] = add nsw i8 [[X:%.*]], 23
186; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[X2]], [[Y:%.*]]
187; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
188; CHECK:       T:
189; CHECK-NEXT:    [[X1:%.*]] = add nsw i8 [[X]], 24
190; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[X1]], [[Y]]
191; CHECK-NEXT:    ret i1 [[R]]
192; CHECK:       F:
193; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
194;
195  %x1 = add nsw i8 %x, 24
196  %x2 = add nsw i8 %x, 23
197
198  %cond = icmp sle i8 %x2, %y
199  br i1 %cond, label %T, label %F
200T:
201  %r = icmp sle i8 %x1, %y
202  ret i1 %r
203F:
204  ret i1 %other
205}
206
207define i1 @src_and_implies_ult(i8 %x, i8 %y, i8 %z, i1 %other) {
208; CHECK-LABEL: @src_and_implies_ult(
209; CHECK-NEXT:    [[COND:%.*]] = icmp ult i8 [[X:%.*]], [[Z:%.*]]
210; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
211; CHECK:       T:
212; CHECK-NEXT:    ret i1 true
213; CHECK:       F:
214; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
215;
216  %cond = icmp ult i8 %x, %z
217  br i1 %cond, label %T, label %F
218T:
219  %and = and i8 %z, %x
220  %r = icmp ult i8 %and, %z
221  ret i1 %r
222F:
223  ret i1 %other
224}
225
226define i1 @src_and_implies_ult_fail(i8 %x, i8 %y, i8 %z, i1 %other) {
227; CHECK-LABEL: @src_and_implies_ult_fail(
228; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ugt i8 [[X:%.*]], [[Z:%.*]]
229; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
230; CHECK:       T:
231; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Z]]
232; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[AND]], [[Z]]
233; CHECK-NEXT:    ret i1 [[R]]
234; CHECK:       F:
235; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
236;
237  %cond = icmp ule i8 %x, %z
238  br i1 %cond, label %T, label %F
239T:
240  %and = and i8 %x, %z
241  %r = icmp ult i8 %and, %z
242  ret i1 %r
243F:
244  ret i1 %other
245}
246
247define i1 @src_and_implies_slt_fail(i8 %x, i8 %y, i8 %z, i1 %other) {
248; CHECK-LABEL: @src_and_implies_slt_fail(
249; CHECK-NEXT:    [[COND:%.*]] = icmp slt i8 [[X:%.*]], [[Z:%.*]]
250; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
251; CHECK:       T:
252; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
253; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[AND]], [[Z]]
254; CHECK-NEXT:    ret i1 [[R]]
255; CHECK:       F:
256; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
257;
258  %cond = icmp slt i8 %x, %z
259  br i1 %cond, label %T, label %F
260T:
261  %and = and i8 %x, %y
262  %r = icmp slt i8 %and, %z
263  ret i1 %r
264F:
265  ret i1 %other
266}
267
268define i1 @src_or_implies_ule(i8 %x, i8 %y, i8 %z, i1 %other) {
269; CHECK-LABEL: @src_or_implies_ule(
270; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
271; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ult i8 [[Z:%.*]], [[OR]]
272; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
273; CHECK:       T:
274; CHECK-NEXT:    ret i1 true
275; CHECK:       F:
276; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
277;
278  %or = or i8 %y, %x
279  %cond = icmp uge i8 %z, %or
280  br i1 %cond, label %T, label %F
281T:
282  %r = icmp ule i8 %x, %z
283  ret i1 %r
284F:
285  ret i1 %other
286}
287
288define i1 @src_or_implies_false_ugt_todo(i8 %x, i8 %y, i8 %z, i1 %other) {
289; CHECK-LABEL: @src_or_implies_false_ugt_todo(
290; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
291; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i8 [[OR]], [[Z:%.*]]
292; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
293; CHECK:       T:
294; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
295; CHECK:       F:
296; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], [[Z]]
297; CHECK-NEXT:    ret i1 [[R]]
298;
299  %or = or i8 %x, %y
300  %cond = icmp ugt i8 %or, %z
301  br i1 %cond, label %T, label %F
302T:
303  ret i1 %other
304F:
305  %r = icmp ugt i8 %x, %z
306  ret i1 %r
307
308}
309
310define i1 @src_udiv_implies_ult(i8 %x, i8 %z, i1 %other) {
311; CHECK-LABEL: @src_udiv_implies_ult(
312; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i8 [[Z:%.*]], [[X:%.*]]
313; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
314; CHECK:       T:
315; CHECK-NEXT:    ret i1 true
316; CHECK:       F:
317; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
318;
319  %cond = icmp ugt i8 %z, %x
320  br i1 %cond, label %T, label %F
321T:
322  %and = udiv i8 %x, 3
323  %r = icmp ult i8 %and, %z
324  ret i1 %r
325F:
326  ret i1 %other
327}
328
329define i1 @src_udiv_implies_ult2(i8 %x, i8 %z, i1 %other) {
330; CHECK-LABEL: @src_udiv_implies_ult2(
331; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ugt i8 [[Z:%.*]], [[X:%.*]]
332; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
333; CHECK:       T:
334; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
335; CHECK:       F:
336; CHECK-NEXT:    ret i1 true
337;
338  %cond = icmp ule i8 %z, %x
339  br i1 %cond, label %T, label %F
340T:
341  ret i1 %other
342F:
343  %and = udiv i8 %x, 3
344  %r = icmp ult i8 %and, %z
345  ret i1 %r
346}
347
348define i1 @src_smin_implies_sle(i8 %x, i8 %y, i8 %z, i1 %other) {
349; CHECK-LABEL: @src_smin_implies_sle(
350; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[X:%.*]], [[Z:%.*]]
351; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
352; CHECK:       T:
353; CHECK-NEXT:    ret i1 true
354; CHECK:       F:
355; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
356;
357  %cond = icmp sle i8 %x, %z
358  br i1 %cond, label %T, label %F
359T:
360  %um = call i8 @llvm.smin.i8(i8 %x, i8 %y)
361  %r = icmp sle i8 %um, %z
362  ret i1 %r
363F:
364  ret i1 %other
365}
366
367define i1 @src_umin_implies_ule(i8 %x, i8 %y, i8 %z, i1 %other) {
368; CHECK-LABEL: @src_umin_implies_ule(
369; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ugt i8 [[X:%.*]], [[Z:%.*]]
370; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
371; CHECK:       T:
372; CHECK-NEXT:    ret i1 true
373; CHECK:       F:
374; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
375;
376  %cond = icmp ule i8 %x, %z
377  br i1 %cond, label %T, label %F
378T:
379  %um = call i8 @llvm.umin.i8(i8 %x, i8 %y)
380  %r = icmp ule i8 %um, %z
381  ret i1 %r
382F:
383  ret i1 %other
384}
385
386define i1 @src_umax_implies_ule(i8 %x, i8 %y, i8 %z, i1 %other) {
387; CHECK-LABEL: @src_umax_implies_ule(
388; CHECK-NEXT:    [[UM:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
389; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ugt i8 [[UM]], [[Z:%.*]]
390; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
391; CHECK:       T:
392; CHECK-NEXT:    ret i1 true
393; CHECK:       F:
394; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
395;
396  %um = call i8 @llvm.umax.i8(i8 %x, i8 %y)
397  %cond = icmp ule i8 %um, %z
398  br i1 %cond, label %T, label %F
399T:
400  %r = icmp ule i8 %x, %z
401  ret i1 %r
402F:
403  ret i1 %other
404}
405
406define i1 @src_smax_implies_sle(i8 %x, i8 %y, i8 %z, i1 %other) {
407; CHECK-LABEL: @src_smax_implies_sle(
408; CHECK-NEXT:    [[UM:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
409; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp sgt i8 [[UM]], [[Z:%.*]]
410; CHECK-NEXT:    br i1 [[COND_NOT]], label [[F:%.*]], label [[T:%.*]]
411; CHECK:       T:
412; CHECK-NEXT:    ret i1 true
413; CHECK:       F:
414; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
415;
416  %um = call i8 @llvm.smax.i8(i8 %x, i8 %y)
417  %cond = icmp sle i8 %um, %z
418  br i1 %cond, label %T, label %F
419T:
420  %r = icmp sle i8 %x, %z
421  ret i1 %r
422F:
423  ret i1 %other
424}
425