1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s 3 4; With no-wrap: 5; (X * Y) == 0 --> (X == 0) || (Y == 0) 6; (X * Y) != 0 --> (X != 0) && (Y != 0) 7 8define i1 @mul_nsw_eq0_i8(i8 %x, i8 %y) { 9; CHECK-LABEL: mul_nsw_eq0_i8: 10; CHECK: // %bb.0: 11; CHECK-NEXT: tst w0, #0xff 12; CHECK-NEXT: cset w8, eq 13; CHECK-NEXT: tst w1, #0xff 14; CHECK-NEXT: csinc w0, w8, wzr, ne 15; CHECK-NEXT: ret 16 %m = mul nsw i8 %x, %y 17 %r = icmp eq i8 %m, 0 18 ret i1 %r 19} 20 21; negative test - not valid if mul can overflow 22 23define i1 @mul_eq0_i8(i8 %x, i8 %y) { 24; CHECK-LABEL: mul_eq0_i8: 25; CHECK: // %bb.0: 26; CHECK-NEXT: mul w8, w0, w1 27; CHECK-NEXT: tst w8, #0xff 28; CHECK-NEXT: cset w0, eq 29; CHECK-NEXT: ret 30 %m = mul i8 %x, %y 31 %r = icmp eq i8 %m, 0 32 ret i1 %r 33} 34 35; negative test - don't try with minsize 36 37define i1 @mul_nsw_eq0_i8_size(i8 %x, i8 %y) minsize { 38; CHECK-LABEL: mul_nsw_eq0_i8_size: 39; CHECK: // %bb.0: 40; CHECK-NEXT: mul w8, w0, w1 41; CHECK-NEXT: tst w8, #0xff 42; CHECK-NEXT: cset w0, eq 43; CHECK-NEXT: ret 44 %m = mul nsw i8 %x, %y 45 %r = icmp eq i8 %m, 0 46 ret i1 %r 47} 48 49define i1 @mul_nsw_ne0_i16(i16 %x, i16 %y) { 50; CHECK-LABEL: mul_nsw_ne0_i16: 51; CHECK: // %bb.0: 52; CHECK-NEXT: tst w0, #0xffff 53; CHECK-NEXT: cset w8, ne 54; CHECK-NEXT: tst w1, #0xffff 55; CHECK-NEXT: csel w0, wzr, w8, eq 56; CHECK-NEXT: ret 57 %m = mul nsw i16 %x, %y 58 %r = icmp ne i16 %m, 0 59 ret i1 %r 60} 61 62define i1 @mul_nuw_eq0_i32(i32 %x, i32 %y) { 63; CHECK-LABEL: mul_nuw_eq0_i32: 64; CHECK: // %bb.0: 65; CHECK-NEXT: cmp w0, #0 66; CHECK-NEXT: ccmp w1, #0, #4, ne 67; CHECK-NEXT: cset w0, eq 68; CHECK-NEXT: ret 69 %m = mul nuw i32 %x, %y 70 %r = icmp eq i32 %m, 0 71 ret i1 %r 72} 73 74define i1 @mul_nsw_nuw_ne0_i64(i64 %x, i64 %y) { 75; CHECK-LABEL: mul_nsw_nuw_ne0_i64: 76; CHECK: // %bb.0: 77; CHECK-NEXT: cmp x0, #0 78; CHECK-NEXT: ccmp x1, #0, #4, ne 79; CHECK-NEXT: cset w0, ne 80; CHECK-NEXT: ret 81 %m = mul nsw nuw i64 %x, %y 82 %r = icmp ne i64 %m, 0 83 ret i1 %r 84} 85 86define <16 x i1> @mul_nuw_eq0_v16i8(<16 x i8> %x, <16 x i8> %y) { 87; CHECK-LABEL: mul_nuw_eq0_v16i8: 88; CHECK: // %bb.0: 89; CHECK-NEXT: cmeq v1.16b, v1.16b, #0 90; CHECK-NEXT: cmeq v0.16b, v0.16b, #0 91; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 92; CHECK-NEXT: ret 93 %m = mul nuw <16 x i8> %x, %y 94 %r = icmp eq <16 x i8> %m, zeroinitializer 95 ret <16 x i1> %r 96} 97 98define <4 x i1> @mul_nsw_ne0_v4i32(<4 x i32> %x, <4 x i32> %y) { 99; CHECK-LABEL: mul_nsw_ne0_v4i32: 100; CHECK: // %bb.0: 101; CHECK-NEXT: cmtst v0.4s, v0.4s, v0.4s 102; CHECK-NEXT: cmeq v1.4s, v1.4s, #0 103; CHECK-NEXT: bic v0.16b, v0.16b, v1.16b 104; CHECK-NEXT: xtn v0.4h, v0.4s 105; CHECK-NEXT: ret 106 %m = mul nsw <4 x i32> %x, %y 107 %r = icmp ne <4 x i32> %m, zeroinitializer 108 ret <4 x i1> %r 109} 110 111; negative test - don't try with minsize 112 113define <4 x i1> @mul_nsw_ne0_v4i32_size(<4 x i32> %x, <4 x i32> %y) minsize { 114; CHECK-LABEL: mul_nsw_ne0_v4i32_size: 115; CHECK: // %bb.0: 116; CHECK-NEXT: mul v0.4s, v0.4s, v1.4s 117; CHECK-NEXT: cmtst v0.4s, v0.4s, v0.4s 118; CHECK-NEXT: xtn v0.4h, v0.4s 119; CHECK-NEXT: ret 120 %m = mul nsw <4 x i32> %x, %y 121 %r = icmp ne <4 x i32> %m, zeroinitializer 122 ret <4 x i1> %r 123} 124