1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4define i1 @and_consts(i32 %k, i32 %c1, i32 %c2) {
5; CHECK-LABEL: @and_consts(
6; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[K:%.*]], 12
7; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 12
8; CHECK-NEXT:    ret i1 [[TMP2]]
9;
10  %t1 = and i32 4, %k
11  %t2 = icmp eq i32 %t1, 0
12  %t5 = and i32 8, %k
13  %t6 = icmp eq i32 %t5, 0
14  %or = or i1 %t2, %t6
15  ret i1 %or
16}
17
18define <2 x i1> @and_consts_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
19; CHECK-LABEL: @and_consts_vector(
20; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[K:%.*]], <i32 12, i32 12>
21; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 12, i32 12>
22; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
23;
24  %t1 = and <2 x i32> <i32 4, i32 4>, %k
25  %t2 = icmp eq <2 x i32> %t1, zeroinitializer
26  %t5 = and <2 x i32> <i32 8, i32 8>, %k
27  %t6 = icmp eq <2 x i32> %t5, zeroinitializer
28  %or = or <2 x i1> %t2, %t6
29  ret <2 x i1> %or
30}
31
32define i1 @foo1_and(i32 %k, i32 %c1, i32 %c2) {
33; CHECK-LABEL: @foo1_and(
34; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
35; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
36; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
37; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
38; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
39; CHECK-NEXT:    ret i1 [[TMP3]]
40;
41  %t = shl i32 1, %c1
42  %t4 = shl i32 1, %c2
43  %t1 = and i32 %t, %k
44  %t2 = icmp eq i32 %t1, 0
45  %t5 = and i32 %t4, %k
46  %t6 = icmp eq i32 %t5, 0
47  %or = or i1 %t2, %t6
48  ret i1 %or
49}
50
51define <2 x i1> @foo1_and_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
52; CHECK-LABEL: @foo1_and_vector(
53; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
54; CHECK-NEXT:    [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
55; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
56; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
57; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], [[TMP1]]
58; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
59;
60  %t = shl <2 x i32> <i32 1, i32 1>, %c1
61  %t4 = shl <2 x i32> <i32 1, i32 1>, %c2
62  %t1 = and <2 x i32> %t, %k
63  %t2 = icmp eq <2 x i32> %t1, zeroinitializer
64  %t5 = and <2 x i32> %t4, %k
65  %t6 = icmp eq <2 x i32> %t5, zeroinitializer
66  %or = or <2 x i1> %t2, %t6
67  ret <2 x i1> %or
68}
69
70; Same as above but with operands commuted one of the ands, but not the other.
71define i1 @foo1_and_commuted(i32 %k, i32 %c1, i32 %c2) {
72; CHECK-LABEL: @foo1_and_commuted(
73; CHECK-NEXT:    [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
74; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
75; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
76; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
77; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[K2]], [[TMP1]]
78; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
79; CHECK-NEXT:    ret i1 [[TMP3]]
80;
81  %k2 = mul i32 %k, %k ; to trick the complexity sorting
82  %t = shl i32 1, %c1
83  %t4 = shl i32 1, %c2
84  %t1 = and i32 %k2, %t
85  %t2 = icmp eq i32 %t1, 0
86  %t5 = and i32 %t4, %k2
87  %t6 = icmp eq i32 %t5, 0
88  %or = or i1 %t2, %t6
89  ret i1 %or
90}
91
92define <2 x i1> @foo1_and_commuted_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
93; CHECK-LABEL: @foo1_and_commuted_vector(
94; CHECK-NEXT:    [[K2:%.*]] = mul <2 x i32> [[K:%.*]], [[K]]
95; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
96; CHECK-NEXT:    [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
97; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
98; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[K2]], [[TMP1]]
99; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], [[TMP1]]
100; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
101;
102  %k2 = mul <2 x i32> %k, %k ; to trick the complexity sorting
103  %t = shl <2 x i32> <i32 1, i32 1>, %c1
104  %t4 = shl <2 x i32> <i32 1, i32 1>, %c2
105  %t1 = and <2 x i32> %k2, %t
106  %t2 = icmp eq <2 x i32> %t1, zeroinitializer
107  %t5 = and <2 x i32> %t4, %k2
108  %t6 = icmp eq <2 x i32> %t5, zeroinitializer
109  %or = or <2 x i1> %t2, %t6
110  ret <2 x i1> %or
111}
112
113define i1 @or_consts(i32 %k, i32 %c1, i32 %c2) {
114; CHECK-LABEL: @or_consts(
115; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[K:%.*]], 12
116; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 12
117; CHECK-NEXT:    ret i1 [[TMP2]]
118;
119  %t1 = and i32 4, %k
120  %t2 = icmp ne i32 %t1, 0
121  %t5 = and i32 8, %k
122  %t6 = icmp ne i32 %t5, 0
123  %or = and i1 %t2, %t6
124  ret i1 %or
125}
126
127define <2 x i1> @or_consts_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
128; CHECK-LABEL: @or_consts_vector(
129; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[K:%.*]], <i32 12, i32 12>
130; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 12, i32 12>
131; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
132;
133  %t1 = and <2 x i32> <i32 4, i32 4>, %k
134  %t2 = icmp ne <2 x i32> %t1, zeroinitializer
135  %t5 = and <2 x i32> <i32 8, i32 8>, %k
136  %t6 = icmp ne <2 x i32> %t5, zeroinitializer
137  %or = and <2 x i1> %t2, %t6
138  ret <2 x i1> %or
139}
140
141define i1 @foo1_or(i32 %k, i32 %c1, i32 %c2) {
142; CHECK-LABEL: @foo1_or(
143; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
144; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
145; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
146; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
147; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
148; CHECK-NEXT:    ret i1 [[TMP3]]
149;
150  %t = shl i32 1, %c1
151  %t4 = shl i32 1, %c2
152  %t1 = and i32 %t, %k
153  %t2 = icmp ne i32 %t1, 0
154  %t5 = and i32 %t4, %k
155  %t6 = icmp ne i32 %t5, 0
156  %or = and i1 %t2, %t6
157  ret i1 %or
158}
159
160define <2 x i1> @foo1_or_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
161; CHECK-LABEL: @foo1_or_vector(
162; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
163; CHECK-NEXT:    [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
164; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
165; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
166; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], [[TMP1]]
167; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
168;
169  %t = shl <2 x i32> <i32 1, i32 1>, %c1
170  %t4 = shl <2 x i32> <i32 1, i32 1>, %c2
171  %t1 = and <2 x i32> %t, %k
172  %t2 = icmp ne <2 x i32> %t1, zeroinitializer
173  %t5 = and <2 x i32> %t4, %k
174  %t6 = icmp ne <2 x i32> %t5, zeroinitializer
175  %or = and <2 x i1> %t2, %t6
176  ret <2 x i1> %or
177}
178
179; Same as above but with operands commuted one of the ors, but not the other.
180define i1 @foo1_or_commuted(i32 %k, i32 %c1, i32 %c2) {
181; CHECK-LABEL: @foo1_or_commuted(
182; CHECK-NEXT:    [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
183; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
184; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
185; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
186; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[K2]], [[TMP1]]
187; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
188; CHECK-NEXT:    ret i1 [[TMP3]]
189;
190  %k2 = mul i32 %k, %k ; to trick the complexity sorting
191  %t = shl i32 1, %c1
192  %t4 = shl i32 1, %c2
193  %t1 = and i32 %k2, %t
194  %t2 = icmp ne i32 %t1, 0
195  %t5 = and i32 %t4, %k2
196  %t6 = icmp ne i32 %t5, 0
197  %or = and i1 %t2, %t6
198  ret i1 %or
199}
200
201define <2 x i1> @foo1_or_commuted_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
202; CHECK-LABEL: @foo1_or_commuted_vector(
203; CHECK-NEXT:    [[K2:%.*]] = mul <2 x i32> [[K:%.*]], [[K]]
204; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
205; CHECK-NEXT:    [[T4:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C2:%.*]]
206; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
207; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[K2]], [[TMP1]]
208; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], [[TMP1]]
209; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
210;
211  %k2 = mul <2 x i32> %k, %k ; to trick the complexity sorting
212  %t = shl <2 x i32> <i32 1, i32 1>, %c1
213  %t4 = shl <2 x i32> <i32 1, i32 1>, %c2
214  %t1 = and <2 x i32> %k2, %t
215  %t2 = icmp ne <2 x i32> %t1, zeroinitializer
216  %t5 = and <2 x i32> %t4, %k2
217  %t6 = icmp ne <2 x i32> %t5, zeroinitializer
218  %or = and <2 x i1> %t2, %t6
219  ret <2 x i1> %or
220}
221
222define i1 @foo1_and_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
223; CHECK-LABEL: @foo1_and_signbit_lshr(
224; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
225; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
226; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
227; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
228; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
229; CHECK-NEXT:    ret i1 [[TMP3]]
230;
231  %t = shl i32 1, %c1
232  %t4 = lshr i32 -2147483648, %c2
233  %t1 = and i32 %t, %k
234  %t2 = icmp eq i32 %t1, 0
235  %t5 = and i32 %t4, %k
236  %t6 = icmp eq i32 %t5, 0
237  %or = or i1 %t2, %t6
238  ret i1 %or
239}
240
241define <2 x i1> @foo1_and_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
242; CHECK-LABEL: @foo1_and_signbit_lshr_vector(
243; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
244; CHECK-NEXT:    [[T4:%.*]] = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
245; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
246; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
247; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], [[TMP1]]
248; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
249;
250  %t = shl <2 x i32> <i32 1, i32 1>, %c1
251  %t4 = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, %c2
252  %t1 = and <2 x i32> %t, %k
253  %t2 = icmp eq <2 x i32> %t1, zeroinitializer
254  %t5 = and <2 x i32> %t4, %k
255  %t6 = icmp eq <2 x i32> %t5, zeroinitializer
256  %or = or <2 x i1> %t2, %t6
257  ret <2 x i1> %or
258}
259
260define i1 @foo1_or_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
261; CHECK-LABEL: @foo1_or_signbit_lshr(
262; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
263; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
264; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
265; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
266; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
267; CHECK-NEXT:    ret i1 [[TMP3]]
268;
269  %t = shl i32 1, %c1
270  %t4 = lshr i32 -2147483648, %c2
271  %t1 = and i32 %t, %k
272  %t2 = icmp ne i32 %t1, 0
273  %t5 = and i32 %t4, %k
274  %t6 = icmp ne i32 %t5, 0
275  %or = and i1 %t2, %t6
276  ret i1 %or
277}
278
279define <2 x i1> @foo1_or_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
280; CHECK-LABEL: @foo1_or_signbit_lshr_vector(
281; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
282; CHECK-NEXT:    [[T4:%.*]] = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
283; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
284; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
285; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], [[TMP1]]
286; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
287;
288  %t = shl <2 x i32> <i32 1, i32 1>, %c1
289  %t4 = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, %c2
290  %t1 = and <2 x i32> %t, %k
291  %t2 = icmp ne <2 x i32> %t1, zeroinitializer
292  %t5 = and <2 x i32> %t4, %k
293  %t6 = icmp ne <2 x i32> %t5, zeroinitializer
294  %or = and <2 x i1> %t2, %t6
295  ret <2 x i1> %or
296}
297
298; Same as last two, but shift-of-signbit replaced with 'icmp s*'
299define i1 @foo1_and_signbit_lshr_without_shifting_signbit(i32 %k, i32 %c1, i32 %c2) {
300; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit(
301; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
302; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
303; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
304; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
305; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
306; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
307; CHECK-NEXT:    ret i1 [[OR]]
308;
309  %t0 = shl i32 1, %c1
310  %t1 = and i32 %t0, %k
311  %t2 = icmp eq i32 %t1, 0
312  %t3 = shl i32 %k, %c2
313  %t4 = icmp sgt i32 %t3, -1
314  %or = or i1 %t2, %t4
315  ret i1 %or
316}
317
318define i1 @foo1_or_signbit_lshr_without_shifting_signbit(i32 %k, i32 %c1, i32 %c2) {
319; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit(
320; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
321; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
322; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
323; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
324; CHECK-NEXT:    [[T4:%.*]] = icmp slt i32 [[T3]], 0
325; CHECK-NEXT:    [[OR:%.*]] = and i1 [[T2]], [[T4]]
326; CHECK-NEXT:    ret i1 [[OR]]
327;
328  %t0 = shl i32 1, %c1
329  %t1 = and i32 %t0, %k
330  %t2 = icmp ne i32 %t1, 0
331  %t3 = shl i32 %k, %c2
332  %t4 = icmp slt i32 %t3, 0
333  %or = and i1 %t2, %t4
334  ret i1 %or
335}
336
337; Shift-of-signbit replaced with 'icmp s*' for both sides
338define i1 @foo1_and_signbit_lshr_without_shifting_signbit_both_sides(i32 %k, i32 %c1, i32 %c2) {
339; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_both_sides(
340; CHECK-NEXT:    [[T0:%.*]] = shl i32 [[K:%.*]], [[C1:%.*]]
341; CHECK-NEXT:    [[T2:%.*]] = shl i32 [[K]], [[C2:%.*]]
342; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[T0]], [[T2]]
343; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
344; CHECK-NEXT:    ret i1 [[TMP2]]
345;
346  %t0 = shl i32 %k, %c1
347  %t1 = icmp sgt i32 %t0, -1
348  %t2 = shl i32 %k, %c2
349  %t3 = icmp sgt i32 %t2, -1
350  %or = or i1 %t1, %t3
351  ret i1 %or
352}
353
354define i1 @foo1_or_signbit_lshr_without_shifting_signbit_both_sides(i32 %k, i32 %c1, i32 %c2) {
355; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit_both_sides(
356; CHECK-NEXT:    [[T0:%.*]] = shl i32 [[K:%.*]], [[C1:%.*]]
357; CHECK-NEXT:    [[T2:%.*]] = shl i32 [[K]], [[C2:%.*]]
358; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[T0]], [[T2]]
359; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
360; CHECK-NEXT:    ret i1 [[TMP2]]
361;
362  %t0 = shl i32 %k, %c1
363  %t1 = icmp slt i32 %t0, 0
364  %t2 = shl i32 %k, %c2
365  %t3 = icmp slt i32 %t2, 0
366  %or = and i1 %t1, %t3
367  ret i1 %or
368}
369
370; Extra use
371
372; Expect to fold
373define i1 @foo1_and_extra_use_shl(i32 %k, i32 %c1, i32 %c2, i32* %p) {
374; CHECK-LABEL: @foo1_and_extra_use_shl(
375; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
376; CHECK-NEXT:    store i32 [[T0]], i32* [[P:%.*]], align 4
377; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
378; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
379; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
380; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
381; CHECK-NEXT:    ret i1 [[TMP3]]
382;
383  %t0 = shl i32 1, %c1
384  store i32 %t0, i32* %p  ; extra use of shl
385  %t1 = shl i32 1, %c2
386  %t2 = and i32 %t0, %k
387  %t3 = icmp eq i32 %t2, 0
388  %t4 = and i32 %t1, %k
389  %t5 = icmp eq i32 %t4, 0
390  %or = or i1 %t3, %t5
391  ret i1 %or
392}
393
394; Should not fold
395define i1 @foo1_and_extra_use_and(i32 %k, i32 %c1, i32 %c2, i32* %p) {
396; CHECK-LABEL: @foo1_and_extra_use_and(
397; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
398; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
399; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
400; CHECK-NEXT:    store i32 [[T2]], i32* [[P:%.*]], align 4
401; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
402; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
403; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
404; CHECK-NEXT:    ret i1 [[TMP3]]
405;
406  %t0 = shl i32 1, %c1
407  %t1 = shl i32 1, %c2
408  %t2 = and i32 %t0, %k
409  store i32 %t2, i32* %p  ; extra use of and
410  %t3 = icmp eq i32 %t2, 0
411  %t4 = and i32 %t1, %k
412  %t5 = icmp eq i32 %t4, 0
413  %or = or i1 %t3, %t5
414  ret i1 %or
415}
416
417; Should not fold
418define i1 @foo1_and_extra_use_cmp(i32 %k, i32 %c1, i32 %c2, i1* %p) {
419; CHECK-LABEL: @foo1_and_extra_use_cmp(
420; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
421; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
422; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
423; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T2]], 0
424; CHECK-NEXT:    store i1 [[T3]], i1* [[P:%.*]], align 1
425; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
426; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
427; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
428; CHECK-NEXT:    ret i1 [[TMP3]]
429;
430  %t0 = shl i32 1, %c1
431  %t1 = shl i32 1, %c2
432  %t2 = and i32 %t0, %k
433  %t3 = icmp eq i32 %t2, 0
434  store i1 %t3, i1* %p  ; extra use of cmp
435  %t4 = and i32 %t1, %k
436  %t5 = icmp eq i32 %t4, 0
437  %or = or i1 %t3, %t5
438  ret i1 %or
439}
440
441; Expect to fold
442define i1 @foo1_and_extra_use_shl2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
443; CHECK-LABEL: @foo1_and_extra_use_shl2(
444; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
445; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
446; CHECK-NEXT:    store i32 [[T1]], i32* [[P:%.*]], align 4
447; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
448; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
449; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
450; CHECK-NEXT:    ret i1 [[TMP3]]
451;
452  %t0 = shl i32 1, %c1
453  %t1 = shl i32 1, %c2
454  store i32 %t1, i32* %p  ; extra use of shl
455  %t2 = and i32 %t0, %k
456  %t3 = icmp eq i32 %t2, 0
457  %t4 = and i32 %t1, %k
458  %t5 = icmp eq i32 %t4, 0
459  %or = or i1 %t3, %t5
460  ret i1 %or
461}
462
463; Should not fold
464define i1 @foo1_and_extra_use_and2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
465; CHECK-LABEL: @foo1_and_extra_use_and2(
466; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
467; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
468; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T1]], [[K:%.*]]
469; CHECK-NEXT:    store i32 [[T4]], i32* [[P:%.*]], align 4
470; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
471; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
472; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
473; CHECK-NEXT:    ret i1 [[TMP3]]
474;
475  %t0 = shl i32 1, %c1
476  %t1 = shl i32 1, %c2
477  %t2 = and i32 %t0, %k
478  %t3 = icmp eq i32 %t2, 0
479  %t4 = and i32 %t1, %k
480  store i32 %t4, i32* %p  ; extra use of and
481  %t5 = icmp eq i32 %t4, 0
482  %or = or i1 %t3, %t5
483  ret i1 %or
484}
485
486; Should not fold
487define i1 @foo1_and_extra_use_cmp2(i32 %k, i32 %c1, i32 %c2, i1* %p) {
488; CHECK-LABEL: @foo1_and_extra_use_cmp2(
489; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
490; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
491; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T1]], [[K:%.*]]
492; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], 0
493; CHECK-NEXT:    store i1 [[T5]], i1* [[P:%.*]], align 1
494; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
495; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
496; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
497; CHECK-NEXT:    ret i1 [[TMP3]]
498;
499  %t0 = shl i32 1, %c1
500  %t1 = shl i32 1, %c2
501  %t2 = and i32 %t0, %k
502  %t3 = icmp eq i32 %t2, 0
503  %t4 = and i32 %t1, %k
504  %t5 = icmp eq i32 %t4, 0
505  store i1 %t5, i1* %p  ; extra use of cmp
506  %or = or i1 %t3, %t5
507  ret i1 %or
508}
509
510; Shift-of-signbit replaced with 'icmp s*'
511; Expect to fold
512define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1(i32 %k, i32 %c1, i32 %c2, i32* %p) {
513; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1(
514; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
515; CHECK-NEXT:    store i32 [[T0]], i32* [[P:%.*]], align 4
516; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
517; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
518; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
519; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
520; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
521; CHECK-NEXT:    ret i1 [[OR]]
522;
523  %t0 = shl i32 1, %c1
524  store i32 %t0, i32* %p  ; extra use of shl
525  %t1 = and i32 %t0, %k
526  %t2 = icmp eq i32 %t1, 0
527  %t3 = shl i32 %k, %c2
528  %t4 = icmp sgt i32 %t3, -1
529  %or = or i1 %t2, %t4
530  ret i1 %or
531}
532
533; Not fold
534define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and(i32 %k, i32 %c1, i32 %c2, i32* %p) {
535; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and(
536; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
537; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
538; CHECK-NEXT:    store i32 [[T1]], i32* [[P:%.*]], align 4
539; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
540; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
541; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
542; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
543; CHECK-NEXT:    ret i1 [[OR]]
544;
545  %t0 = shl i32 1, %c1
546  %t1 = and i32 %t0, %k
547  store i32 %t1, i32* %p  ; extra use of and
548  %t2 = icmp eq i32 %t1, 0
549  %t3 = shl i32 %k, %c2
550  %t4 = icmp sgt i32 %t3, -1
551  %or = or i1 %t2, %t4
552  ret i1 %or
553}
554
555; Not fold
556define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1(i32 %k, i32 %c1, i32 %c2, i1* %p) {
557; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1(
558; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
559; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
560; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
561; CHECK-NEXT:    store i1 [[T2]], i1* [[P:%.*]], align 1
562; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
563; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
564; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
565; CHECK-NEXT:    ret i1 [[OR]]
566;
567  %t0 = shl i32 1, %c1
568  %t1 = and i32 %t0, %k
569  %t2 = icmp eq i32 %t1, 0
570  store i1 %t2, i1* %p  ; extra use of cmp
571  %t3 = shl i32 %k, %c2
572  %t4 = icmp sgt i32 %t3, -1
573  %or = or i1 %t2, %t4
574  ret i1 %or
575}
576
577; Not fold
578define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
579; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2(
580; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
581; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
582; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
583; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
584; CHECK-NEXT:    store i32 [[T3]], i32* [[P:%.*]], align 4
585; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
586; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
587; CHECK-NEXT:    ret i1 [[OR]]
588;
589  %t0 = shl i32 1, %c1
590  %t1 = and i32 %t0, %k
591  %t2 = icmp eq i32 %t1, 0
592  %t3 = shl i32 %k, %c2
593  store i32 %t3, i32* %p  ; extra use of shl
594  %t4 = icmp sgt i32 %t3, -1
595  %or = or i1 %t2, %t4
596  ret i1 %or
597}
598
599; Not fold
600define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2(i32 %k, i32 %c1, i32 %c2, i1* %p) {
601; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2(
602; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
603; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
604; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
605; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
606; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
607; CHECK-NEXT:    store i1 [[T4]], i1* [[P:%.*]], align 1
608; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
609; CHECK-NEXT:    ret i1 [[OR]]
610;
611  %t0 = shl i32 1, %c1
612  %t1 = and i32 %t0, %k
613  %t2 = icmp eq i32 %t1, 0
614  %t3 = shl i32 %k, %c2
615  %t4 = icmp sgt i32 %t3, -1
616  store i1 %t4, i1* %p  ; extra use of cmp
617  %or = or i1 %t2, %t4
618  ret i1 %or
619}
620
621; Negative tests
622
623; This test checks that we are not creating additional shift instruction when fold fails.
624define i1 @foo1_and_signbit_lshr_without_shifting_signbit_not_pwr2(i32 %k, i32 %c1, i32 %c2) {
625; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_not_pwr2(
626; CHECK-NEXT:    [[T0:%.*]] = shl i32 3, [[C1:%.*]]
627; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
628; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
629; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
630; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
631; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
632; CHECK-NEXT:    ret i1 [[OR]]
633;
634  %t0 = shl i32 3, %c1
635  %t1 = and i32 %t0, %k
636  %t2 = icmp eq i32 %t1, 0
637  %t3 = shl i32 %k, %c2
638  %t4 = icmp sgt i32 %t3, -1
639  %or = or i1 %t2, %t4
640  ret i1 %or
641}
642