@@ -263,3 +263,113 @@ entry:
263263 %conv = zext i1 %cmp to i8
264264 ret i8 %conv
265265}
266+
267+ ; Test ANDS.
268+ define i32 @test1_ands (i32 %a ) {
269+ ; CHECK-LABEL: test1_ands:
270+ ; CHECK: // %bb.0: // %entry
271+ ; CHECK-NEXT: mov w8, #1024 // =0x400
272+ ; CHECK-NEXT: movk w8, #32, lsl #16
273+ ; CHECK-NEXT: ands w8, w0, w8
274+ ; CHECK-NEXT: csel w0, w8, wzr, eq
275+ ; CHECK-NEXT: ret
276+ entry:
277+ %ands = and i32 %a , 2098176
278+ %c = icmp eq i32 %ands , 0
279+ %r = select i1 %c , i32 %ands , i32 0
280+ ret i32 %r
281+ }
282+
283+ ; This constant should not be split because it can be handled by one mov.
284+ define i32 @test2_ands (i32 %a ) {
285+ ; CHECK-LABEL: test2_ands:
286+ ; CHECK: // %bb.0: // %entry
287+ ; CHECK-NEXT: mov w8, #135 // =0x87
288+ ; CHECK-NEXT: ands w8, w0, w8
289+ ; CHECK-NEXT: csel w0, w8, wzr, eq
290+ ; CHECK-NEXT: ret
291+ entry:
292+ %ands = and i32 %a , 135
293+ %c = icmp eq i32 %ands , 0
294+ %r = select i1 %c , i32 %ands , i32 0
295+ ret i32 %r
296+ }
297+
298+ ; This constant should not be split because the split immediate is not valid
299+ ; bitmask immediate.
300+ define i32 @test3_ands (i32 %a ) {
301+ ; CHECK-LABEL: test3_ands:
302+ ; CHECK: // %bb.0: // %entry
303+ ; CHECK-NEXT: mov w8, #1024 // =0x400
304+ ; CHECK-NEXT: movk w8, #33, lsl #16
305+ ; CHECK-NEXT: ands w8, w0, w8
306+ ; CHECK-NEXT: csel w0, w8, wzr, eq
307+ ; CHECK-NEXT: ret
308+ entry:
309+ %ands = and i32 %a , 2163712
310+ %c = icmp eq i32 %ands , 0
311+ %r = select i1 %c , i32 %ands , i32 0
312+ ret i32 %r
313+ }
314+
315+ define i64 @test4_ands (i64 %a ) {
316+ ; CHECK-LABEL: test4_ands:
317+ ; CHECK: // %bb.0: // %entry
318+ ; CHECK-NEXT: mov w8, #1024 // =0x400
319+ ; CHECK-NEXT: movk w8, #32, lsl #16
320+ ; CHECK-NEXT: ands x8, x0, x8
321+ ; CHECK-NEXT: csel x0, x8, xzr, eq
322+ ; CHECK-NEXT: ret
323+ entry:
324+ %ands = and i64 %a , 2098176
325+ %c = icmp eq i64 %ands , 0
326+ %r = select i1 %c , i64 %ands , i64 0
327+ ret i64 %r
328+ }
329+
330+ define i64 @test5_ands (i64 %a ) {
331+ ; CHECK-LABEL: test5_ands:
332+ ; CHECK: // %bb.0: // %entry
333+ ; CHECK-NEXT: mov x8, #16384 // =0x4000
334+ ; CHECK-NEXT: movk x8, #2, lsl #32
335+ ; CHECK-NEXT: ands x8, x0, x8
336+ ; CHECK-NEXT: csel x0, x8, xzr, eq
337+ ; CHECK-NEXT: ret
338+ entry:
339+ %ands = and i64 %a , 8589950976
340+ %c = icmp eq i64 %ands , 0
341+ %r = select i1 %c , i64 %ands , i64 0
342+ ret i64 %r
343+ }
344+
345+ ; This constant should not be split because it can be handled by one mov.
346+ define i64 @test6_ands (i64 %a ) {
347+ ; CHECK-LABEL: test6_ands:
348+ ; CHECK: // %bb.0: // %entry
349+ ; CHECK-NEXT: mov w8, #135 // =0x87
350+ ; CHECK-NEXT: ands x8, x0, x8
351+ ; CHECK-NEXT: csel x0, x8, xzr, eq
352+ ; CHECK-NEXT: ret
353+ entry:
354+ %ands = and i64 %a , 135
355+ %c = icmp eq i64 %ands , 0
356+ %r = select i1 %c , i64 %ands , i64 0
357+ ret i64 %r
358+ }
359+
360+ ; This constant should not be split because the split immediate is not valid
361+ ; bitmask immediate.
362+ define i64 @test7_ands (i64 %a ) {
363+ ; CHECK-LABEL: test7_ands:
364+ ; CHECK: // %bb.0: // %entry
365+ ; CHECK-NEXT: mov w8, #1024 // =0x400
366+ ; CHECK-NEXT: movk w8, #33, lsl #16
367+ ; CHECK-NEXT: ands x8, x0, x8
368+ ; CHECK-NEXT: csel x0, x8, xzr, eq
369+ ; CHECK-NEXT: ret
370+ entry:
371+ %ands = and i64 %a , 2163712
372+ %c = icmp eq i64 %ands , 0
373+ %r = select i1 %c , i64 %ands , i64 0
374+ ret i64 %r
375+ }
0 commit comments