xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-or-of-select-with-zero.ll (revision f4f6566e44566f3d8cf9517767d457227125ca93)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use.i8(i8)
5declare void @use.i1(i1)
6define i1 @src_tv_eq(i1 %c0, i8 %x, i8 %yy) {
7; CHECK-LABEL: @src_tv_eq(
8; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
9; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[C0:%.*]]
10; CHECK-NEXT:    ret i1 [[R]]
11;
12  %y = add nuw i8 %yy, 1
13  %sel = select i1 %c0, i8 0, i8 %y
14  %selx = or i8 %sel, %x
15  %r = icmp eq i8 %selx, 0
16  ret i1 %r
17}
18
19define i1 @src_tv_eq_multiuse_or_fail(i1 %c0, i8 %x, i8 %yy) {
20; CHECK-LABEL: @src_tv_eq_multiuse_or_fail(
21; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
22; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]]
23; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
24; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[SELX]], 0
25; CHECK-NEXT:    call void @use.i8(i8 [[SELX]])
26; CHECK-NEXT:    ret i1 [[R]]
27;
28  %y = add nuw i8 %yy, 1
29  %sel = select i1 %c0, i8 0, i8 %y
30  %selx = or i8 %sel, %x
31  %r = icmp eq i8 %selx, 0
32  call void @use.i8(i8 %selx)
33  ret i1 %r
34}
35
36define i1 @src_tv_eq_fail_tv_nonzero(i1 %c0, i8 %x, i8 %yy) {
37; CHECK-LABEL: @src_tv_eq_fail_tv_nonzero(
38; CHECK-NEXT:    [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1
39; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0:%.*]], i8 1, i8 [[Y]]
40; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
41; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[SELX]], 0
42; CHECK-NEXT:    ret i1 [[R]]
43;
44  %y = add nsw i8 %yy, 1
45  %sel = select i1 %c0, i8 1, i8 %y
46  %selx = or i8 %sel, %x
47  %r = icmp eq i8 %selx, 0
48  ret i1 %r
49}
50
51define i1 @src_fv_ne(i1 %c0, i8 %x, i8 %yy) {
52; CHECK-LABEL: @src_fv_ne(
53; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
54; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[C0:%.*]]
55; CHECK-NEXT:    ret i1 [[R]]
56;
57  %y = add nuw i8 %yy, 1
58  %sel = select i1 %c0, i8 %y, i8 0
59  %selx = or i8 %sel, %x
60  %r = icmp ne i8 %selx, 0
61  ret i1 %r
62}
63
64define i1 @src_fv_ne_fail_maybe_zero(i1 %c0, i8 %x, i8 %yy) {
65; CHECK-LABEL: @src_fv_ne_fail_maybe_zero(
66; CHECK-NEXT:    [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1
67; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0
68; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
69; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[SELX]], 0
70; CHECK-NEXT:    ret i1 [[R]]
71;
72  %y = add nsw i8 %yy, 1
73  %sel = select i1 %c0, i8 %y, i8 0
74  %selx = or i8 %sel, %x
75  %r = icmp ne i8 %selx, 0
76  ret i1 %r
77}
78
79define i1 @src_tv_ne(i1 %c0, i8 %x, i8 %yy) {
80; CHECK-LABEL: @src_tv_ne(
81; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[C0:%.*]], true
82; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[X:%.*]], 0
83; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP2]], [[TMP1]]
84; CHECK-NEXT:    ret i1 [[R]]
85;
86  %y = add nuw i8 %yy, 1
87  %sel = select i1 %c0, i8 0, i8 %y
88  %selx = or i8 %sel, %x
89  %r = icmp ne i8 %selx, 0
90  ret i1 %r
91}
92
93define i1 @src_tv_ne_fail_cmp_nonzero(i1 %c0, i8 %x, i8 %yy) {
94; CHECK-LABEL: @src_tv_ne_fail_cmp_nonzero(
95; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
96; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]]
97; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
98; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[SELX]], 1
99; CHECK-NEXT:    ret i1 [[R]]
100;
101  %y = add nuw i8 %yy, 1
102  %sel = select i1 %c0, i8 0, i8 %y
103  %selx = or i8 %sel, %x
104  %r = icmp ne i8 %selx, 1
105  ret i1 %r
106}
107
108define i1 @src_fv_eq(i1 %c0, i8 %x, i8 %yy) {
109; CHECK-LABEL: @src_fv_eq(
110; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[C0:%.*]], true
111; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[X:%.*]], 0
112; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP2]], [[TMP1]]
113; CHECK-NEXT:    ret i1 [[R]]
114;
115  %y = add nuw i8 %yy, 1
116  %sel = select i1 %c0, i8 %y, i8 0
117  %selx = or i8 %sel, %x
118  %r = icmp eq i8 %selx, 0
119  ret i1 %r
120}
121
122define i1 @src_fv_eq_fail_cant_invert(i1 %c0, i8 %x, i8 %yy) {
123; CHECK-LABEL: @src_fv_eq_fail_cant_invert(
124; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
125; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0
126; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
127; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[SELX]], 0
128; CHECK-NEXT:    call void @use.i8(i8 [[SEL]])
129; CHECK-NEXT:    ret i1 [[R]]
130;
131  %y = add nuw i8 %yy, 1
132  %sel = select i1 %c0, i8 %y, i8 0
133  %selx = or i8 %sel, %x
134  %r = icmp eq i8 %selx, 0
135  call void @use.i8(i8 %sel)
136  ret i1 %r
137}
138
139define i1 @src_fv_eq_fail_cant_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
140; CHECK-LABEL: @src_fv_eq_fail_cant_invert2(
141; CHECK-NEXT:    [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
142; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
143; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0
144; CHECK-NEXT:    [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]]
145; CHECK-NEXT:    [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]]
146; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
147; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[SELX]], 0
148; CHECK-NEXT:    call void @use.i8(i8 [[SEL]])
149; CHECK-NEXT:    call void @use.i8(i8 [[SEL_OTHER]])
150; CHECK-NEXT:    ret i1 [[R]]
151;
152  %c0 = icmp ugt i8 %a, %b
153  %y = add nuw i8 %yy, 1
154  %sel = select i1 %c0, i8 %y, i8 0
155  %cc = or i1 %c0, %c1
156  %sel_other = select i1 %cc, i8 %y, i8 %b
157
158  %selx = or i8 %sel, %x
159  %r = icmp eq i8 %selx, 0
160  call void @use.i8(i8 %sel)
161  call void @use.i8(i8 %sel_other)
162  ret i1 %r
163}
164
165define i1 @src_fv_eq_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
166; CHECK-LABEL: @src_fv_eq_invert2(
167; CHECK-NEXT:    [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
168; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
169; CHECK-NEXT:    [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]]
170; CHECK-NEXT:    [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]]
171; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[C0]], true
172; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[X:%.*]], 0
173; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP2]], [[TMP1]]
174; CHECK-NEXT:    call void @use.i8(i8 [[SEL_OTHER]])
175; CHECK-NEXT:    ret i1 [[R]]
176;
177  %c0 = icmp ugt i8 %a, %b
178  %y = add nuw i8 %yy, 1
179  %sel = select i1 %c0, i8 %y, i8 0
180  %cc = or i1 %c0, %c1
181  %sel_other = select i1 %cc, i8 %y, i8 %b
182
183  %selx = or i8 %sel, %x
184  %r = icmp eq i8 %selx, 0
185  call void @use.i8(i8 %sel_other)
186  ret i1 %r
187}
188
189
190
191
192define i1 @src_fv_eq_invert2_fail_wrong_binop(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
193; CHECK-LABEL: @src_fv_eq_invert2_fail_wrong_binop(
194; CHECK-NEXT:    [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
195; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
196; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0
197; CHECK-NEXT:    [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]]
198; CHECK-NEXT:    [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]]
199; CHECK-NEXT:    [[SELX:%.*]] = sub i8 0, [[X:%.*]]
200; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[SEL]], [[SELX]]
201; CHECK-NEXT:    call void @use.i8(i8 [[SEL_OTHER]])
202; CHECK-NEXT:    ret i1 [[R]]
203;
204  %c0 = icmp ugt i8 %a, %b
205  %y = add nuw i8 %yy, 1
206  %sel = select i1 %c0, i8 %y, i8 0
207  %cc = or i1 %c0, %c1
208  %sel_other = select i1 %cc, i8 %y, i8 %b
209
210  %selx = add i8 %sel, %x
211  %r = icmp eq i8 %selx, 0
212  call void @use.i8(i8 %sel_other)
213  ret i1 %r
214}
215
216define i1 @src_fv_eq_invert2_fail_bad_sel(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
217; CHECK-LABEL: @src_fv_eq_invert2_fail_bad_sel(
218; CHECK-NEXT:    [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
219; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
220; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0]], i8 [[YY]], i8 0
221; CHECK-NEXT:    [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]]
222; CHECK-NEXT:    [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]]
223; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
224; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[SELX]], 0
225; CHECK-NEXT:    call void @use.i8(i8 [[SEL_OTHER]])
226; CHECK-NEXT:    call void @use.i8(i8 [[YY]])
227; CHECK-NEXT:    ret i1 [[R]]
228;
229  %c0 = icmp ugt i8 %a, %b
230  %y = add nuw i8 %yy, 1
231  %sel = select i1 %c0, i8 %yy, i8 0
232  %cc = or i1 %c0, %c1
233  %sel_other = select i1 %cc, i8 %y, i8 %b
234
235  %selx = or i8 %sel, %x
236  %r = icmp eq i8 %selx, 0
237  call void @use.i8(i8 %sel_other)
238  call void @use.i8(i8 %yy)
239  ret i1 %r
240}
241
242define i1 @src_fv_eq_invert3(i8 %a, i8 %b, i8 %x, i8 %yy) {
243; CHECK-LABEL: @src_fv_eq_invert3(
244; CHECK-NEXT:    [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
245; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
246; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0
247; CHECK-NEXT:    [[SEL_OTHER:%.*]] = select i1 [[C0]], i8 [[Y]], i8 [[B]]
248; CHECK-NEXT:    [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]]
249; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[SELX]], 0
250; CHECK-NEXT:    call void @use.i8(i8 [[SEL_OTHER]])
251; CHECK-NEXT:    call void @use.i8(i8 [[SEL]])
252; CHECK-NEXT:    ret i1 [[R]]
253;
254  %c0 = icmp ugt i8 %a, %b
255  %y = add nuw i8 %yy, 1
256  %sel = select i1 %c0, i8 %y, i8 0
257  %sel_other = select i1 %c0, i8 %y, i8 %b
258
259  %selx = or i8 %sel, %x
260  %r = icmp eq i8 %selx, 0
261  call void @use.i8(i8 %sel_other)
262  call void @use.i8(i8 %sel)
263  ret i1 %r
264}
265
266
267define i1 @src_tv_ne_invert(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) {
268; CHECK-LABEL: @src_tv_ne_invert(
269; CHECK-NEXT:    [[NOT_C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
270; CHECK-NEXT:    call void @use.i1(i1 [[NOT_C0]])
271; CHECK-NEXT:    [[C0:%.*]] = xor i1 [[NOT_C0]], true
272; CHECK-NEXT:    [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
273; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[NOT_C0]], i8 [[Y]], i8 0
274; CHECK-NEXT:    [[CC:%.*]] = or i1 [[C1:%.*]], [[C0]]
275; CHECK-NEXT:    [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]]
276; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
277; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[NOT_C0]]
278; CHECK-NEXT:    call void @use.i8(i8 [[SEL]])
279; CHECK-NEXT:    call void @use.i8(i8 [[SEL_OTHER]])
280; CHECK-NEXT:    ret i1 [[R]]
281;
282  %not_c0 = icmp ugt i8 %a, %b
283  call void @use.i1(i1 %not_c0)
284  %c0 = xor i1 %not_c0, true
285  %y = add nuw i8 %yy, 1
286  %sel = select i1 %c0, i8 0, i8 %y
287  %cc = or i1 %c0, %c1
288  %sel_other = select i1 %cc, i8 %y, i8 %b
289
290  %selx = or i8 %sel, %x
291  %r = icmp ne i8 %selx, 0
292  call void @use.i8(i8 %sel)
293  call void @use.i8(i8 %sel_other)
294  ret i1 %r
295}
296
297; Make sure we don't crash on this case.
298
299define <4 x i1> @pr119063(<4 x i32> %x, i1 %cond) {
300; CHECK-LABEL: @pr119063(
301; CHECK-NEXT:  entry:
302; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], <4 x i32> splat (i32 1), <4 x i32> zeroinitializer
303; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[SEL]], [[X:%.*]]
304; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <4 x i32> [[OR]], zeroinitializer
305; CHECK-NEXT:    ret <4 x i1> [[CMP]]
306;
307entry:
308  %sel = select i1 %cond, <4 x i32> splat (i32 1), <4 x i32> zeroinitializer
309  %or = or <4 x i32> %sel, %x
310  %cmp = icmp ne <4 x i32> %or, zeroinitializer
311  ret <4 x i1> %cmp
312}
313