1; RUN: opt -instcombine -S -o - %s | FileCheck %s
2
3define i1 @masked_and_notallzeroes(i32 %A) {
4; CHECK-LABEL: @masked_and_notallzeroes
5; CHECK: [[MASK:%.*]] = and i32 %A, 7
6; CHECK: icmp ne i32 [[MASK]], 0
7; CHECK-NOT: and i32 %A, 39
8; CHECK: ret i1
9
10  %mask1 = and i32 %A, 7
11  %tst1 = icmp ne i32 %mask1, 0
12
13  %mask2 = and i32 %A, 39
14  %tst2 = icmp ne i32 %mask2, 0
15
16  %res = and i1 %tst1, %tst2
17  ret i1 %res
18}
19
20define i1 @masked_or_allzeroes(i32 %A) {
21; CHECK-LABEL: @masked_or_allzeroes
22; CHECK: [[MASK:%.*]] = and i32 %A, 7
23; CHECK: icmp eq i32 [[MASK]], 0
24; CHECK-NOT: and i32 %A, 39
25; CHECK: ret i1
26
27  %mask1 = and i32 %A, 7
28  %tst1 = icmp eq i32 %mask1, 0
29
30  %mask2 = and i32 %A, 39
31  %tst2 = icmp eq i32 %mask2, 0
32
33  %res = or i1 %tst1, %tst2
34  ret i1 %res
35}
36
37define i1 @masked_and_notallones(i32 %A) {
38; CHECK-LABEL: @masked_and_notallones
39; CHECK: [[MASK:%.*]] = and i32 %A, 7
40; CHECK: icmp ne i32 [[MASK]], 7
41; CHECK-NOT: and i32 %A, 39
42; CHECK: ret i1
43
44  %mask1 = and i32 %A, 7
45  %tst1 = icmp ne i32 %mask1, 7
46
47  %mask2 = and i32 %A, 39
48  %tst2 = icmp ne i32 %mask2, 39
49
50  %res = and i1 %tst1, %tst2
51  ret i1 %res
52}
53
54define i1 @masked_or_allones(i32 %A) {
55; CHECK-LABEL: @masked_or_allones
56; CHECK: [[MASK:%.*]] = and i32 %A, 7
57; CHECK: icmp eq i32 [[MASK]], 7
58; CHECK-NOT: and i32 %A, 39
59; CHECK: ret i1
60
61  %mask1 = and i32 %A, 7
62  %tst1 = icmp eq i32 %mask1, 7
63
64  %mask2 = and i32 %A, 39
65  %tst2 = icmp eq i32 %mask2, 39
66
67  %res = or i1 %tst1, %tst2
68  ret i1 %res
69}
70
71define i1 @masked_and_notA(i32 %A) {
72; CHECK-LABEL: @masked_and_notA
73; CHECK: [[MASK:%.*]] = and i32 %A, 39
74; CHECK: icmp ne i32 [[MASK]], %A
75; CHECK-NOT: and i32 %A, 7
76; CHECK: ret i1
77
78  %mask1 = and i32 %A, 7
79  %tst1 = icmp ne i32 %mask1, %A
80
81  %mask2 = and i32 %A, 39
82  %tst2 = icmp ne i32 %mask2, %A
83
84  %res = and i1 %tst1, %tst2
85  ret i1 %res
86}
87
88define i1 @masked_or_A(i32 %A) {
89; CHECK-LABEL: @masked_or_A
90; CHECK: [[MASK:%.*]] = and i32 %A, 39
91; CHECK: icmp eq i32 [[MASK]], %A
92; CHECK-NOT: and i32 %A, 7
93; CHECK: ret i1
94
95  %mask1 = and i32 %A, 7
96  %tst1 = icmp eq i32 %mask1, %A
97
98  %mask2 = and i32 %A, 39
99  %tst2 = icmp eq i32 %mask2, %A
100
101  %res = or i1 %tst1, %tst2
102  ret i1 %res
103}
104
105define i1 @masked_or_allzeroes_notoptimised(i32 %A) {
106; CHECK-LABEL: @masked_or_allzeroes_notoptimised
107; CHECK: [[MASK:%.*]] = and i32 %A, 15
108; CHECK: icmp eq i32 [[MASK]], 0
109; CHECK: [[MASK:%.*]] = and i32 %A, 39
110; CHECK: icmp eq i32 [[MASK]], 0
111; CHECK: ret i1
112
113  %mask1 = and i32 %A, 15
114  %tst1 = icmp eq i32 %mask1, 0
115
116  %mask2 = and i32 %A, 39
117  %tst2 = icmp eq i32 %mask2, 0
118
119  %res = or i1 %tst1, %tst2
120  ret i1 %res
121}
122
123define i1 @nomask_lhs(i32 %in) {
124; CHECK-LABEL: @nomask_lhs
125; CHECK: [[MASK:%.*]] = and i32 %in, 1
126; CHECK: icmp eq i32 [[MASK]], 0
127; CHECK-NOT: icmp
128; CHECK: ret i1
129  %tst1 = icmp eq i32 %in, 0
130
131  %masked = and i32 %in, 1
132  %tst2 = icmp eq i32 %masked, 0
133
134  %val = or i1 %tst1, %tst2
135  ret i1 %val
136}
137
138
139define i1 @nomask_rhs(i32 %in) {
140; CHECK-LABEL: @nomask_rhs
141; CHECK: [[MASK:%.*]] = and i32 %in, 1
142; CHECK: icmp eq i32 [[MASK]], 0
143; CHECK-NOT: icmp
144; CHECK: ret i1
145  %masked = and i32 %in, 1
146  %tst1 = icmp eq i32 %masked, 0
147
148  %tst2 = icmp eq i32 %in, 0
149
150  %val = or i1 %tst1, %tst2
151  ret i1 %val
152}
153
154define i1 @fold_mask_cmps_to_false(i32 %x) {
155; CHECK-LABEL: @fold_mask_cmps_to_false
156; CHECK: ret i1 false
157  %1 = and i32 %x, 2147483647
158  %2 = icmp eq i32 %1, 0
159  %3 = icmp eq i32 %x, 2147483647
160  %4 = and i1 %3, %2
161  ret i1 %4
162}
163
164define i1 @fold_mask_cmps_to_true(i32 %x) {
165; CHECK-LABEL: @fold_mask_cmps_to_true
166; CHECK: ret i1 true
167  %1 = and i32 %x, 2147483647
168  %2 = icmp ne i32 %1, 0
169  %3 = icmp ne i32 %x, 2147483647
170  %4 = or i1 %3, %2
171  ret i1 %4
172}
173