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