1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
6 define i1 @mul_mask_pow2_eq0(i8 %x) {
7 ; CHECK-LABEL: @mul_mask_pow2_eq0(
8 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 1
9 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
10 ; CHECK-NEXT: ret i1 [[CMP]]
14 %cmp = icmp eq i8 %and, 0
18 ; TODO: Demanded bits does not convert the mul to shift,
19 ; but the 'and' could be of 'x' directly.
21 define i1 @mul_mask_pow2_ne0_use1(i8 %x) {
22 ; CHECK-LABEL: @mul_mask_pow2_ne0_use1(
23 ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 40
24 ; CHECK-NEXT: call void @use(i8 [[MUL]])
25 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[MUL]], 8
26 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
27 ; CHECK-NEXT: ret i1 [[CMP]]
30 call void @use(i8 %mul)
32 %cmp = icmp ne i8 %and, 0
36 ; negative test - extra use of 'and' would require more instructions
38 define i1 @mul_mask_pow2_ne0_use2(i8 %x) {
39 ; CHECK-LABEL: @mul_mask_pow2_ne0_use2(
40 ; CHECK-NEXT: [[MUL:%.*]] = shl i8 [[X:%.*]], 3
41 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[MUL]], 8
42 ; CHECK-NEXT: call void @use(i8 [[AND]])
43 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
44 ; CHECK-NEXT: ret i1 [[CMP]]
48 call void @use(i8 %and)
49 %cmp = icmp ne i8 %and, 0
53 ; non-equality predicates are converted to equality
55 define i1 @mul_mask_pow2_sgt0(i8 %x) {
56 ; CHECK-LABEL: @mul_mask_pow2_sgt0(
57 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 1
58 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
59 ; CHECK-NEXT: ret i1 [[CMP]]
63 %cmp = icmp sgt i8 %and, 0
67 ; unnecessary mask bits are removed
69 define i1 @mul_mask_fakepow2_ne0(i8 %x) {
70 ; CHECK-LABEL: @mul_mask_fakepow2_ne0(
71 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 1
72 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
73 ; CHECK-NEXT: ret i1 [[CMP]]
77 %cmp = icmp ne i8 %and, 0
81 ; non-zero cmp constant is converted
83 define i1 @mul_mask_pow2_eq4(i8 %x) {
84 ; CHECK-LABEL: @mul_mask_pow2_eq4(
85 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 1
86 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
87 ; CHECK-NEXT: ret i1 [[CMP]]
91 %cmp = icmp eq i8 %and, 4
95 ; negative test - must be pow2 mask constant
97 define i1 @mul_mask_notpow2_ne(i8 %x) {
98 ; CHECK-LABEL: @mul_mask_notpow2_ne(
99 ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 12
100 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[MUL]], 12
101 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
102 ; CHECK-NEXT: ret i1 [[CMP]]
105 %and = and i8 %mul, 12
106 %cmp = icmp ne i8 %and, 0
110 define i1 @pr40493(i32 %area) {
111 ; CHECK-LABEL: @pr40493(
112 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AREA:%.*]], 1
113 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
114 ; CHECK-NEXT: ret i1 [[CMP]]
116 %mul = mul i32 %area, 12
117 %rem = and i32 %mul, 4
118 %cmp = icmp eq i32 %rem, 0
122 define i1 @pr40493_neg1(i32 %area) {
123 ; CHECK-LABEL: @pr40493_neg1(
124 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[AREA:%.*]], 3
125 ; CHECK-NEXT: [[REM:%.*]] = and i32 [[MUL]], 4
126 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 0
127 ; CHECK-NEXT: ret i1 [[CMP]]
129 %mul = mul i32 %area, 11
130 %rem = and i32 %mul, 4
131 %cmp = icmp eq i32 %rem, 0
135 define i1 @pr40493_neg2(i32 %area) {
136 ; CHECK-LABEL: @pr40493_neg2(
137 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[AREA:%.*]], 12
138 ; CHECK-NEXT: [[REM:%.*]] = and i32 [[MUL]], 12
139 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 0
140 ; CHECK-NEXT: ret i1 [[CMP]]
142 %mul = mul i32 %area, 12
143 %rem = and i32 %mul, 15
144 %cmp = icmp eq i32 %rem, 0
148 define i32 @pr40493_neg3(i32 %area) {
149 ; CHECK-LABEL: @pr40493_neg3(
150 ; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[AREA:%.*]], 2
151 ; CHECK-NEXT: [[REM:%.*]] = and i32 [[MUL]], 4
152 ; CHECK-NEXT: ret i32 [[REM]]
154 %mul = mul i32 %area, 12
155 %rem = and i32 %mul, 4
159 define <4 x i1> @pr40493_vec1(<4 x i32> %area) {
160 ; CHECK-LABEL: @pr40493_vec1(
161 ; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[AREA:%.*]], splat (i32 1)
162 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer
163 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
165 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 12>
166 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 4>
167 %cmp = icmp eq <4 x i32> %rem, zeroinitializer
171 define <4 x i1> @pr40493_vec2(<4 x i32> %area) {
172 ; CHECK-LABEL: @pr40493_vec2(
173 ; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], <i32 12, i32 12, i32 12, i32 undef>
174 ; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], splat (i32 4)
175 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer
176 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
178 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 undef>
179 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 4>
180 %cmp = icmp eq <4 x i32> %rem, zeroinitializer
184 define <4 x i1> @pr40493_vec3(<4 x i32> %area) {
185 ; CHECK-LABEL: @pr40493_vec3(
186 ; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], splat (i32 12)
187 ; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], <i32 4, i32 4, i32 4, i32 undef>
188 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer
189 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
191 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 12>
192 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 undef>
193 %cmp = icmp eq <4 x i32> %rem, zeroinitializer
197 define <4 x i1> @pr40493_vec4(<4 x i32> %area) {
198 ; CHECK-LABEL: @pr40493_vec4(
199 ; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], <i32 12, i32 12, i32 12, i32 undef>
200 ; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], <i32 4, i32 4, i32 4, i32 undef>
201 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer
202 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
204 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 undef>
205 %rem = and <4 x i32> %mul, <i32 4, i32 4, i32 4, i32 undef>
206 %cmp = icmp eq <4 x i32> %rem, zeroinitializer
210 define <4 x i1> @pr40493_vec5(<4 x i32> %area) {
211 ; CHECK-LABEL: @pr40493_vec5(
212 ; CHECK-NEXT: [[MUL:%.*]] = mul <4 x i32> [[AREA:%.*]], <i32 12, i32 12, i32 20, i32 20>
213 ; CHECK-NEXT: [[REM:%.*]] = and <4 x i32> [[MUL]], <i32 2, i32 4, i32 2, i32 4>
214 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[REM]], zeroinitializer
215 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
217 %mul = mul <4 x i32> %area, <i32 12, i32 12, i32 20, i32 20>
218 %rem = and <4 x i32> %mul, <i32 2, i32 4, i32 2, i32 4>
219 %cmp = icmp eq <4 x i32> %rem, zeroinitializer
223 define i1 @pr51551(i32 %x, i32 %y) {
224 ; CHECK-LABEL: @pr51551(
225 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
226 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
227 ; CHECK-NEXT: ret i1 [[CMP]]
231 %mul = mul nsw i32 %t1, %x
232 %and = and i32 %mul, 3
233 %cmp = icmp eq i32 %and, 0
237 define i1 @pr51551_2(i32 %x, i32 %y) {
238 ; CHECK-LABEL: @pr51551_2(
239 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
240 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
241 ; CHECK-NEXT: ret i1 [[CMP]]
245 %mul = mul nsw i32 %t1, %x
246 %and = and i32 %mul, 1
247 %cmp = icmp eq i32 %and, 0
251 define i1 @pr51551_neg1(i32 %x, i32 %y) {
252 ; CHECK-LABEL: @pr51551_neg1(
253 ; CHECK-NEXT: [[T0:%.*]] = and i32 [[Y:%.*]], 4
254 ; CHECK-NEXT: [[T1:%.*]] = or disjoint i32 [[T0]], 1
255 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T1]], [[X:%.*]]
256 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[MUL]], 7
257 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
258 ; CHECK-NEXT: ret i1 [[CMP]]
262 %mul = mul nsw i32 %t1, %x
263 %and = and i32 %mul, 7
264 %cmp = icmp eq i32 %and, 0
268 define i1 @pr51551_neg2(i32 %x, i32 %y) {
269 ; CHECK-LABEL: @pr51551_neg2(
270 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[Y:%.*]] to i1
271 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X:%.*]], 7
272 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[TMP2]], 0
273 ; CHECK-NEXT: [[DOTNOT:%.*]] = xor i1 [[TMP1]], true
274 ; CHECK-NEXT: [[CMP:%.*]] = select i1 [[DOTNOT]], i1 true, i1 [[CMP1]]
275 ; CHECK-NEXT: ret i1 [[CMP]]
278 %mul = mul nsw i32 %t0, %x
279 %and = and i32 %mul, 7
280 %cmp = icmp eq i32 %and, 0
284 define i32 @pr51551_demand3bits(i32 %x, i32 %y) {
285 ; CHECK-LABEL: @pr51551_demand3bits(
286 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 7
287 ; CHECK-NEXT: ret i32 [[AND]]
291 %mul = mul nsw i32 %t1, %x
292 %and = and i32 %mul, 7