[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-mul-and.ll
blob7fa75184c1cf3bc73bd33bc0e6d16c48c600ba76
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i8)
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]]
12   %mul = mul i8 %x, 44
13   %and = and i8 %mul, 4
14   %cmp = icmp eq i8 %and, 0
15   ret i1 %cmp
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]]
29   %mul = mul i8 %x, 40
30   call void @use(i8 %mul)
31   %and = and i8 %mul, 8
32   %cmp = icmp ne i8 %and, 0
33   ret i1 %cmp
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]]
46   %mul = mul i8 %x, 40
47   %and = and i8 %mul, 8
48   call void @use(i8 %and)
49   %cmp = icmp ne i8 %and, 0
50   ret i1 %cmp
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]]
61   %mul = mul i8 %x, 44
62   %and = and i8 %mul, 4
63   %cmp = icmp sgt i8 %and, 0
64   ret i1 %cmp
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]]
75   %mul = mul i8 %x, 44
76   %and = and i8 %mul, 5
77   %cmp = icmp ne i8 %and, 0
78   ret i1 %cmp
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]]
89   %mul = mul i8 %x, 44
90   %and = and i8 %mul, 4
91   %cmp = icmp eq i8 %and, 4
92   ret i1 %cmp
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]]
104   %mul = mul i8 %x, 60
105   %and = and i8 %mul, 12
106   %cmp = icmp ne i8 %and, 0
107   ret i1 %cmp
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
119   ret i1 %cmp
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
132   ret i1 %cmp
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
145   ret i1 %cmp
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
156   ret i32 %rem
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
168   ret <4 x i1> %cmp
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
181   ret <4 x i1> %cmp
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
194   ret <4 x i1> %cmp
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
207   ret <4 x i1> %cmp
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
220   ret <4 x i1> %cmp
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]]
229   %t0 = and i32 %y, -7
230   %t1 = or i32 %t0, 1
231   %mul = mul nsw i32 %t1, %x
232   %and = and i32 %mul, 3
233   %cmp = icmp eq i32 %and, 0
234   ret i1 %cmp
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]]
243   %t0 = and i32 %y, -7
244   %t1 = or i32 %t0, 1
245   %mul = mul nsw i32 %t1, %x
246   %and = and i32 %mul, 1
247   %cmp = icmp eq i32 %and, 0
248   ret i1 %cmp
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]]
260   %t0 = and i32 %y, -3
261   %t1 = or i32 %t0, 1
262   %mul = mul nsw i32 %t1, %x
263   %and = and i32 %mul, 7
264   %cmp = icmp eq i32 %and, 0
265   ret i1 %cmp
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]]
277   %t0 = and i32 %y, -7
278   %mul = mul nsw i32 %t0, %x
279   %and = and i32 %mul, 7
280   %cmp = icmp eq i32 %and, 0
281   ret i1 %cmp
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]]
289   %t0 = and i32 %y, -7
290   %t1 = or i32 %t0, 1
291   %mul = mul nsw i32 %t1, %x
292   %and = and i32 %mul, 7
293   ret i32 %and