diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index a7abb58064a53..59cdd7f071c09 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -740,6 +740,8 @@ def AArch64vsli : SDNode<"AArch64ISD::VSLI", SDT_AArch64vshiftinsert>; def AArch64vsri : SDNode<"AArch64ISD::VSRI", SDT_AArch64vshiftinsert>; def AArch64bsp: SDNode<"AArch64ISD::BSP", SDT_AArch64trivec>; +def AArch64nbsl: PatFrag<(ops node:$Op1, node:$Op2, node:$Op3), + (vnot (AArch64bsp node:$Op1, node:$Op2, node:$Op3))>; def AArch64cmeq: SDNode<"AArch64ISD::CMEQ", SDT_AArch64binvec>; def AArch64cmge: SDNode<"AArch64ISD::CMGE", SDT_AArch64binvec>; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 525ae79da9962..06b943cf95146 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -3760,7 +3760,7 @@ let Predicates = [HasSVE2orSME] in { defm BSL_ZZZZ : sve2_int_bitwise_ternary_op<0b001, "bsl", int_aarch64_sve_bsl, AArch64bsp>; defm BSL1N_ZZZZ : sve2_int_bitwise_ternary_op<0b011, "bsl1n", int_aarch64_sve_bsl1n>; defm BSL2N_ZZZZ : sve2_int_bitwise_ternary_op<0b101, "bsl2n", int_aarch64_sve_bsl2n>; - defm NBSL_ZZZZ : sve2_int_bitwise_ternary_op<0b111, "nbsl", int_aarch64_sve_nbsl>; + defm NBSL_ZZZZ : sve2_int_bitwise_ternary_op<0b111, "nbsl", int_aarch64_sve_nbsl, AArch64nbsl>; // SVE2 bitwise xor and rotate right by immediate defm XAR_ZZZI : sve2_int_rotate_right_imm<"xar", int_aarch64_sve_xar>; diff --git a/llvm/test/CodeGen/AArch64/sve2-bsl.ll b/llvm/test/CodeGen/AArch64/sve2-bsl.ll index 23b2622f5f586..ef7d4abe5c5f4 100644 --- a/llvm/test/CodeGen/AArch64/sve2-bsl.ll +++ b/llvm/test/CodeGen/AArch64/sve2-bsl.ll @@ -41,3 +41,55 @@ define @no_bsl_fold( %a, %c = or %1, %2 ret %c } + +define @nbsl_i8( %a, %b) { +; CHECK-LABEL: nbsl_i8: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z2.b, #127 // =0x7f +; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d +; CHECK-NEXT: ret + %1 = and %a, splat(i8 127) + %2 = and %b, splat(i8 -128) + %3 = or %1, %2 + %4 = xor %3, splat(i8 -1) + ret %4 +} + +define @nbsl_i16( %a, %b) { +; CHECK-LABEL: nbsl_i16: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z2.h, #32767 // =0x7fff +; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d +; CHECK-NEXT: ret + %1 = and %a, splat(i16 32767) + %2 = and %b, splat(i16 -32768) + %3 = or %1, %2 + %4 = xor %3, splat(i16 -1) + ret %4 +} + +define @nbsl_i32( %a, %b) { +; CHECK-LABEL: nbsl_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z2.s, #0x7fffffff +; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d +; CHECK-NEXT: ret + %1 = and %a, splat(i32 2147483647) + %2 = and %b, splat(i32 -2147483648) + %3 = or %1, %2 + %4 = xor %3, splat(i32 -1) + ret %4 +} + +define @nbsl_i64( %a, %b) { +; CHECK-LABEL: nbsl_i64: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z2.d, #0x7fffffffffffffff +; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d +; CHECK-NEXT: ret + %1 = and %a, splat(i64 9223372036854775807) + %2 = and %b, splat(i64 -9223372036854775808) + %3 = or %1, %2 + %4 = xor %3, splat(i64 -1) + ret %4 +}