1; This test makes sure that these instructions are properly eliminated.
2;
3; RUN: opt < %s -instcombine -S | \
4; RUN:    not grep "tobool"
5; END.
6define i32 @main(i32 %argc, i8** %argv) nounwind ssp {
7entry:
8  %and = and i32 %argc, 1                         ; <i32> [#uses=1]
9  %tobool = icmp ne i32 %and, 0                   ; <i1> [#uses=1]
10  %and2 = and i32 %argc, 2                        ; <i32> [#uses=1]
11  %tobool3 = icmp ne i32 %and2, 0                 ; <i1> [#uses=1]
12  %or.cond = and i1 %tobool, %tobool3             ; <i1> [#uses=1]
13  %retval.0 = select i1 %or.cond, i32 2, i32 1    ; <i32> [#uses=1]
14  ret i32 %retval.0
15}
16
17define i32 @main2(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
18entry:
19  %and = and i32 %argc, 1                         ; <i32> [#uses=1]
20  %tobool = icmp eq i32 %and, 0                   ; <i1> [#uses=1]
21  %and2 = and i32 %argc, 2                        ; <i32> [#uses=1]
22  %tobool3 = icmp eq i32 %and2, 0                 ; <i1> [#uses=1]
23  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
24  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
25  ret i32 %storemerge
26}
27
28; tests to check combining (icmp eq (A & B), C) & (icmp eq (A & D), E)
29; tests to check if (icmp eq (A & B), 0) is treated like (icmp eq (A & B), B)
30; if B is a single bit constant
31
32; (icmp eq (A & B), 0) & (icmp eq (A & D), 0) -> (icmp eq (A & (B|D)), 0)
33define i32 @main3(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
34entry:
35  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
36  %tobool = icmp eq i32 %and, 0                   ; <i1> [#uses=1]
37  %and2 = and i32 %argc, 48                       ; <i32> [#uses=1]
38  %tobool3 = icmp eq i32 %and2, 0                 ; <i1> [#uses=1]
39  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
40  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
41  ret i32 %storemerge
42}
43
44define i32 @main3b(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
45entry:
46  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
47  %tobool = icmp eq i32 %and, 0                   ; <i1> [#uses=1]
48  %and2 = and i32 %argc, 16                       ; <i32> [#uses=1]
49  %tobool3 = icmp ne i32 %and2, 16                 ; <i1> [#uses=1]
50  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
51  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
52  ret i32 %storemerge
53}
54
55define i32 @main3e_like(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
56           nounwind readnone ssp {
57entry:
58  %and = and i32 %argc, %argc2                    ; <i32> [#uses=1]
59  %tobool = icmp eq i32 %and, 0                   ; <i1> [#uses=1]
60  %and2 = and i32 %argc, %argc3                   ; <i32> [#uses=1]
61  %tobool3 = icmp eq i32 %and2, 0                 ; <i1> [#uses=1]
62  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
63  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
64  ret i32 %storemerge
65}
66
67; (icmp ne (A & B), 0) | (icmp ne (A & D), 0) -> (icmp ne (A & (B|D)), 0)
68define i32 @main3c(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
69entry:
70  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
71  %tobool = icmp ne i32 %and, 0                   ; <i1> [#uses=1]
72  %and2 = and i32 %argc, 48                       ; <i32> [#uses=1]
73  %tobool3 = icmp ne i32 %and2, 0                 ; <i1> [#uses=1]
74  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
75  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
76  ret i32 %storemerge
77}
78
79define i32 @main3d(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
80entry:
81  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
82  %tobool = icmp ne i32 %and, 0                   ; <i1> [#uses=1]
83  %and2 = and i32 %argc, 16                       ; <i32> [#uses=1]
84  %tobool3 = icmp eq i32 %and2, 16                ; <i1> [#uses=1]
85  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
86  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
87  ret i32 %storemerge
88}
89
90define i32 @main3f_like(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
91           nounwind readnone ssp {
92entry:
93  %and = and i32 %argc, %argc2                    ; <i32> [#uses=1]
94  %tobool = icmp ne i32 %and, 0                   ; <i1> [#uses=1]
95  %and2 = and i32 %argc, %argc3                   ; <i32> [#uses=1]
96  %tobool3 = icmp ne i32 %and2, 0                 ; <i1> [#uses=1]
97  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
98  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
99  ret i32 %storemerge
100}
101
102; (icmp eq (A & B), B) & (icmp eq (A & D), D) -> (icmp eq (A & (B|D)), (B|D))
103define i32 @main4(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
104entry:
105  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
106  %tobool = icmp eq i32 %and, 7                   ; <i1> [#uses=1]
107  %and2 = and i32 %argc, 48                       ; <i32> [#uses=1]
108  %tobool3 = icmp eq i32 %and2, 48                ; <i1> [#uses=1]
109  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
110  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
111  ret i32 %storemerge
112}
113
114define i32 @main4b(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
115entry:
116  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
117  %tobool = icmp eq i32 %and, 7                   ; <i1> [#uses=1]
118  %and2 = and i32 %argc, 16                       ; <i32> [#uses=1]
119  %tobool3 = icmp ne i32 %and2, 0                 ; <i1> [#uses=1]
120  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
121  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
122  ret i32 %storemerge
123}
124
125define i32 @main4e_like(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
126           nounwind readnone ssp {
127entry:
128  %and = and i32 %argc, %argc2                    ; <i32> [#uses=1]
129  %tobool = icmp eq i32 %and, %argc2              ; <i1> [#uses=1]
130  %and2 = and i32 %argc, %argc3                   ; <i32> [#uses=1]
131  %tobool3 = icmp eq i32 %and2, %argc3            ; <i1> [#uses=1]
132  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
133  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
134  ret i32 %storemerge
135}
136
137; (icmp ne (A & B), B) | (icmp ne (A & D), D) -> (icmp ne (A & (B|D)), (B|D))
138define i32 @main4c(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
139entry:
140  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
141  %tobool = icmp ne i32 %and, 7                   ; <i1> [#uses=1]
142  %and2 = and i32 %argc, 48                       ; <i32> [#uses=1]
143  %tobool3 = icmp ne i32 %and2, 48                ; <i1> [#uses=1]
144  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
145  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
146  ret i32 %storemerge
147}
148
149define i32 @main4d(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
150entry:
151  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
152  %tobool = icmp ne i32 %and, 7                   ; <i1> [#uses=1]
153  %and2 = and i32 %argc, 16                       ; <i32> [#uses=1]
154  %tobool3 = icmp eq i32 %and2, 0                 ; <i1> [#uses=1]
155  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
156  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
157  ret i32 %storemerge
158}
159
160define i32 @main4f_like(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
161           nounwind readnone ssp {
162entry:
163  %and = and i32 %argc, %argc2                    ; <i32> [#uses=1]
164  %tobool = icmp ne i32 %and, %argc2              ; <i1> [#uses=1]
165  %and2 = and i32 %argc, %argc3                   ; <i32> [#uses=1]
166  %tobool3 = icmp ne i32 %and2, %argc3            ; <i1> [#uses=1]
167  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
168  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
169  ret i32 %storemerge
170}
171
172; (icmp eq (A & B), A) & (icmp eq (A & D), A) -> (icmp eq (A & (B&D)), A)
173define i32 @main5_like(i32 %argc, i32 %argc2, i8** nocapture %argv)
174           nounwind readnone ssp {
175entry:
176  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
177  %tobool = icmp eq i32 %and, 7                   ; <i1> [#uses=1]
178  %and2 = and i32 %argc2, 7                       ; <i32> [#uses=1]
179  %tobool3 = icmp eq i32 %and2, 7                 ; <i1> [#uses=1]
180  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
181  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
182  ret i32 %storemerge
183}
184
185define i32 @main5e_like(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
186           nounwind readnone ssp {
187entry:
188  %and = and i32 %argc, %argc2                    ; <i32> [#uses=1]
189  %tobool = icmp eq i32 %and, %argc               ; <i1> [#uses=1]
190  %and2 = and i32 %argc, %argc3                   ; <i32> [#uses=1]
191  %tobool3 = icmp eq i32 %and2, %argc             ; <i1> [#uses=1]
192  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
193  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
194  ret i32 %storemerge
195}
196
197; (icmp ne (A & B), A) | (icmp ne (A & D), A) -> (icmp ne (A & (B&D)), A)
198define i32 @main5c_like(i32 %argc, i32 %argc2, i8** nocapture %argv)
199           nounwind readnone ssp {
200entry:
201  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
202  %tobool = icmp ne i32 %and, 7                   ; <i1> [#uses=1]
203  %and2 = and i32 %argc2, 7                       ; <i32> [#uses=1]
204  %tobool3 = icmp ne i32 %and2, 7                 ; <i1> [#uses=1]
205  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
206  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
207  ret i32 %storemerge
208}
209
210define i32 @main5f_like(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
211           nounwind readnone ssp {
212entry:
213  %and = and i32 %argc, %argc2                    ; <i32> [#uses=1]
214  %tobool = icmp ne i32 %and, %argc               ; <i1> [#uses=1]
215  %and2 = and i32 %argc, %argc3                   ; <i32> [#uses=1]
216  %tobool3 = icmp ne i32 %and2, %argc             ; <i1> [#uses=1]
217  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
218  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
219  ret i32 %storemerge
220}
221
222; (icmp eq (A & B), C) & (icmp eq (A & D), E) -> (icmp eq (A & (B|D)), (C|E))
223; if B, C, D, E are constant, and it's possible
224define i32 @main6(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
225entry:
226  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
227  %tobool = icmp eq i32 %and, 3                   ; <i1> [#uses=1]
228  %and2 = and i32 %argc, 48                       ; <i32> [#uses=1]
229  %tobool3 = icmp eq i32 %and2, 16                ; <i1> [#uses=1]
230  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
231  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
232  ret i32 %storemerge
233}
234
235define i32 @main6b(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
236entry:
237  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
238  %tobool = icmp eq i32 %and, 3                   ; <i1> [#uses=1]
239  %and2 = and i32 %argc, 16                       ; <i32> [#uses=1]
240  %tobool3 = icmp ne i32 %and2, 0                 ; <i1> [#uses=1]
241  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
242  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
243  ret i32 %storemerge
244}
245
246; (icmp ne (A & B), C) | (icmp ne (A & D), E) -> (icmp ne (A & (B|D)), (C|E))
247; if B, C, D, E are constant, and it's possible
248define i32 @main6c(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
249entry:
250  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
251  %tobool = icmp ne i32 %and, 3                   ; <i1> [#uses=1]
252  %and2 = and i32 %argc, 48                       ; <i32> [#uses=1]
253  %tobool3 = icmp ne i32 %and2, 16                ; <i1> [#uses=1]
254  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
255  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
256  ret i32 %storemerge
257}
258
259define i32 @main6d(i32 %argc, i8** nocapture %argv) nounwind readnone ssp {
260entry:
261  %and = and i32 %argc, 7                         ; <i32> [#uses=1]
262  %tobool = icmp ne i32 %and, 3                   ; <i1> [#uses=1]
263  %and2 = and i32 %argc, 16                       ; <i32> [#uses=1]
264  %tobool3 = icmp eq i32 %and2, 0                 ; <i1> [#uses=1]
265  %or.cond = or i1 %tobool, %tobool3              ; <i1> [#uses=1]
266  %storemerge = select i1 %or.cond, i32 0, i32 1  ; <i32> [#uses=1]
267  ret i32 %storemerge
268}
269
270; test parameter permutations
271; (B & A) == B & (D & A) == D
272define i32 @main7a(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
273           nounwind readnone ssp {
274entry:
275  %and1 = and i32 %argc2, %argc                   ; <i32> [#uses=1]
276  %tobool = icmp eq i32 %and1, %argc2              ; <i1> [#uses=1]
277  %and2 = and i32 %argc3, %argc                   ; <i32> [#uses=1]
278  %tobool3 = icmp eq i32 %and2, %argc3            ; <i1> [#uses=1]
279  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
280  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
281  ret i32 %storemerge
282}
283
284; B == (A & B) & D == (A & D)
285define i32 @main7b(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
286           nounwind readnone ssp {
287entry:
288  %and1 = and i32 %argc, %argc2                   ; <i32> [#uses=1]
289  %tobool = icmp eq i32 %argc2, %and1             ; <i1> [#uses=1]
290  %and2 = and i32 %argc, %argc3                   ; <i32> [#uses=1]
291  %tobool3 = icmp eq i32 %argc3, %and2            ; <i1> [#uses=1]
292  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
293  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
294  ret i32 %storemerge
295}
296
297; B == (B & A) & D == (D & A)
298define i32 @main7c(i32 %argc, i32 %argc2, i32 %argc3, i8** nocapture %argv)
299           nounwind readnone ssp {
300entry:
301  %and1 = and i32 %argc2, %argc                   ; <i32> [#uses=1]
302  %tobool = icmp eq i32 %argc2, %and1             ; <i1> [#uses=1]
303  %and2 = and i32 %argc3, %argc                   ; <i32> [#uses=1]
304  %tobool3 = icmp eq i32 %argc3, %and2            ; <i1> [#uses=1]
305  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
306  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
307  ret i32 %storemerge
308}
309
310; (A & (B & C)) == (B & C) & (A & (D & E)) == (D & E)
311define i32 @main7d(i32 %argc, i32 %argc2, i32 %argc3,
312                   i32 %argc4, i32 %argc5, i8** nocapture %argv)
313           nounwind readnone ssp {
314entry:
315  %bc = and i32 %argc2, %argc4                    ; <i32> [#uses=1]
316  %de = and i32 %argc3, %argc5                    ; <i32> [#uses=1]
317  %and1 = and i32 %argc, %bc                      ; <i32> [#uses=1]
318  %tobool = icmp eq i32 %and1, %bc                ; <i1> [#uses=1]
319  %and2 = and i32 %argc, %de                      ; <i32> [#uses=1]
320  %tobool3 = icmp eq i32 %and2, %de               ; <i1> [#uses=1]
321  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
322  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
323  ret i32 %storemerge
324}
325
326; ((B & C) & A) == (B & C) & ((D & E) & A) == (D & E)
327define i32 @main7e(i32 %argc, i32 %argc2, i32 %argc3,
328                   i32 %argc4, i32 %argc5, i8** nocapture %argv)
329           nounwind readnone ssp {
330entry:
331  %bc = and i32 %argc2, %argc4                    ; <i32> [#uses=1]
332  %de = and i32 %argc3, %argc5                    ; <i32> [#uses=1]
333  %and1 = and i32 %bc, %argc                      ; <i32> [#uses=1]
334  %tobool = icmp eq i32 %and1, %bc                ; <i1> [#uses=1]
335  %and2 = and i32 %de, %argc                      ; <i32> [#uses=1]
336  %tobool3 = icmp eq i32 %and2, %de               ; <i1> [#uses=1]
337  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
338  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
339  ret i32 %storemerge
340}
341
342; (B & C) == (A & (B & C)) & (D & E) == (A & (D & E))
343define i32 @main7f(i32 %argc, i32 %argc2, i32 %argc3,
344                   i32 %argc4, i32 %argc5, i8** nocapture %argv)
345           nounwind readnone ssp {
346entry:
347  %bc = and i32 %argc2, %argc4                    ; <i32> [#uses=1]
348  %de = and i32 %argc3, %argc5                    ; <i32> [#uses=1]
349  %and1 = and i32 %argc, %bc                      ; <i32> [#uses=1]
350  %tobool = icmp eq i32 %bc, %and1                ; <i1> [#uses=1]
351  %and2 = and i32 %argc, %de                      ; <i32> [#uses=1]
352  %tobool3 = icmp eq i32 %de, %and2               ; <i1> [#uses=1]
353  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
354  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
355  ret i32 %storemerge
356}
357
358; (B & C) == ((B & C) & A) & (D & E) == ((D & E) & A)
359define i32 @main7g(i32 %argc, i32 %argc2, i32 %argc3,
360                   i32 %argc4, i32 %argc5, i8** nocapture %argv)
361           nounwind readnone ssp {
362entry:
363  %bc = and i32 %argc2, %argc4                    ; <i32> [#uses=1]
364  %de = and i32 %argc3, %argc5                    ; <i32> [#uses=1]
365  %and1 = and i32 %bc, %argc                      ; <i32> [#uses=1]
366  %tobool = icmp eq i32 %bc, %and1                ; <i1> [#uses=1]
367  %and2 = and i32 %de, %argc                      ; <i32> [#uses=1]
368  %tobool3 = icmp eq i32 %de, %and2               ; <i1> [#uses=1]
369  %and.cond = and i1 %tobool, %tobool3            ; <i1> [#uses=1]
370  %storemerge = select i1 %and.cond, i32 0, i32 1 ; <i32> [#uses=1]
371  ret i32 %storemerge
372}
373