diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -444,6 +444,9 @@ def AArch64fmls_m1 : fma_patfrags; def AArch64mul_m1 : VSelectCommPredOrPassthruPatFrags; +def AArch64and_m1 : VSelectUnpredOrPassthruPatFrags; +def AArch64orr_m1 : VSelectUnpredOrPassthruPatFrags; +def AArch64eor_m1 : VSelectUnpredOrPassthruPatFrags; def AArch64smax_m1 : VSelectCommPredOrPassthruPatFrags; def AArch64umax_m1 : VSelectCommPredOrPassthruPatFrags; def AArch64smin_m1 : VSelectCommPredOrPassthruPatFrags; @@ -474,9 +477,9 @@ defm SUB_ZPmZ : sve_int_bin_pred_arit_0<0b001, "sub", "SUB_ZPZZ", AArch64sub_m1, DestructiveBinaryCommWithRev, "SUBR_ZPmZ">; defm SUBR_ZPmZ : sve_int_bin_pred_arit_0<0b011, "subr", "SUBR_ZPZZ", int_aarch64_sve_subr, DestructiveBinaryCommWithRev, "SUB_ZPmZ", /*isReverseInstr*/ 1>; - defm ORR_ZPmZ : sve_int_bin_pred_log<0b000, "orr", "ORR_ZPZZ", int_aarch64_sve_orr, DestructiveBinaryComm>; - defm EOR_ZPmZ : sve_int_bin_pred_log<0b001, "eor", "EOR_ZPZZ", int_aarch64_sve_eor, DestructiveBinaryComm>; - defm AND_ZPmZ : sve_int_bin_pred_log<0b010, "and", "AND_ZPZZ", int_aarch64_sve_and, DestructiveBinaryComm>; + defm ORR_ZPmZ : sve_int_bin_pred_log<0b000, "orr", "ORR_ZPZZ", AArch64orr_m1, DestructiveBinaryComm>; + defm EOR_ZPmZ : sve_int_bin_pred_log<0b001, "eor", "EOR_ZPZZ", AArch64eor_m1, DestructiveBinaryComm>; + defm AND_ZPmZ : sve_int_bin_pred_log<0b010, "and", "AND_ZPZZ", AArch64and_m1, DestructiveBinaryComm>; defm BIC_ZPmZ : sve_int_bin_pred_log<0b011, "bic", "BIC_ZPZZ", int_aarch64_sve_bic, DestructiveBinary>; } // End HasSVEorSME diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -647,6 +647,14 @@ ], [{ return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse(); }]>; +// Similarly matches either an intrinsic, or an unpredicated operation with a select +class VSelectUnpredOrPassthruPatFrags +: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [ + (intrinsic node:$Pg, node:$Op1, node:$Op2), + (vselect node:$Pg, (sdnode node:$Op1, node:$Op2), node:$Op1), + ], [{ + return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse(); + }]>; // // Pseudo -> Instruction mappings diff --git a/llvm/test/CodeGen/AArch64/sve-pred-selectop2.ll b/llvm/test/CodeGen/AArch64/sve-pred-selectop2.ll --- a/llvm/test/CodeGen/AArch64/sve-pred-selectop2.ll +++ b/llvm/test/CodeGen/AArch64/sve-pred-selectop2.ll @@ -535,9 +535,8 @@ ; CHECK-LABEL: and_nxv2i64_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.d -; CHECK-NEXT: and z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.d, p0/z, z2.d, #0 -; CHECK-NEXT: mov z0.d, p0/m, z1.d +; CHECK-NEXT: and z0.d, p0/m, z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -550,9 +549,8 @@ ; CHECK-LABEL: and_nxv4i32_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.s -; CHECK-NEXT: and z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.s, p0/z, z2.s, #0 -; CHECK-NEXT: mov z0.s, p0/m, z1.s +; CHECK-NEXT: and z0.s, p0/m, z0.s, z1.s ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -565,9 +563,8 @@ ; CHECK-LABEL: and_nxv8i16_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.h -; CHECK-NEXT: and z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.h, p0/z, z2.h, #0 -; CHECK-NEXT: mov z0.h, p0/m, z1.h +; CHECK-NEXT: and z0.h, p0/m, z0.h, z1.h ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -580,9 +577,8 @@ ; CHECK-LABEL: and_nxv16i8_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.b -; CHECK-NEXT: and z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.b, p0/z, z2.b, #0 -; CHECK-NEXT: mov z0.b, p0/m, z1.b +; CHECK-NEXT: and z0.b, p0/m, z0.b, z1.b ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -595,9 +591,8 @@ ; CHECK-LABEL: or_nxv2i64_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.d -; CHECK-NEXT: orr z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.d, p0/z, z2.d, #0 -; CHECK-NEXT: mov z0.d, p0/m, z1.d +; CHECK-NEXT: orr z0.d, p0/m, z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -610,9 +605,8 @@ ; CHECK-LABEL: or_nxv4i32_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.s -; CHECK-NEXT: orr z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.s, p0/z, z2.s, #0 -; CHECK-NEXT: mov z0.s, p0/m, z1.s +; CHECK-NEXT: orr z0.s, p0/m, z0.s, z1.s ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -625,9 +619,8 @@ ; CHECK-LABEL: or_nxv8i16_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.h -; CHECK-NEXT: orr z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.h, p0/z, z2.h, #0 -; CHECK-NEXT: mov z0.h, p0/m, z1.h +; CHECK-NEXT: orr z0.h, p0/m, z0.h, z1.h ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -640,9 +633,8 @@ ; CHECK-LABEL: or_nxv16i8_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.b -; CHECK-NEXT: orr z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.b, p0/z, z2.b, #0 -; CHECK-NEXT: mov z0.b, p0/m, z1.b +; CHECK-NEXT: orr z0.b, p0/m, z0.b, z1.b ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -655,9 +647,8 @@ ; CHECK-LABEL: xor_nxv2i64_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.d -; CHECK-NEXT: eor z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.d, p0/z, z2.d, #0 -; CHECK-NEXT: mov z0.d, p0/m, z1.d +; CHECK-NEXT: eor z0.d, p0/m, z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -670,9 +661,8 @@ ; CHECK-LABEL: xor_nxv4i32_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.s -; CHECK-NEXT: eor z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.s, p0/z, z2.s, #0 -; CHECK-NEXT: mov z0.s, p0/m, z1.s +; CHECK-NEXT: eor z0.s, p0/m, z0.s, z1.s ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -685,9 +675,8 @@ ; CHECK-LABEL: xor_nxv8i16_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.h -; CHECK-NEXT: eor z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.h, p0/z, z2.h, #0 -; CHECK-NEXT: mov z0.h, p0/m, z1.h +; CHECK-NEXT: eor z0.h, p0/m, z0.h, z1.h ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -700,9 +689,8 @@ ; CHECK-LABEL: xor_nxv16i8_x: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.b -; CHECK-NEXT: eor z1.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.b, p0/z, z2.b, #0 -; CHECK-NEXT: mov z0.b, p0/m, z1.b +; CHECK-NEXT: eor z0.b, p0/m, z0.b, z1.b ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1835,9 +1823,9 @@ ; CHECK-LABEL: and_nxv2i64_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.d -; CHECK-NEXT: and z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.d, p0/z, z2.d, #0 -; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: and z1.d, p0/m, z1.d, z0.d +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1850,9 +1838,9 @@ ; CHECK-LABEL: and_nxv4i32_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.s -; CHECK-NEXT: and z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.s, p0/z, z2.s, #0 -; CHECK-NEXT: sel z0.s, p0, z0.s, z1.s +; CHECK-NEXT: and z1.s, p0/m, z1.s, z0.s +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1865,9 +1853,9 @@ ; CHECK-LABEL: and_nxv8i16_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.h -; CHECK-NEXT: and z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.h, p0/z, z2.h, #0 -; CHECK-NEXT: sel z0.h, p0, z0.h, z1.h +; CHECK-NEXT: and z1.h, p0/m, z1.h, z0.h +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1880,9 +1868,9 @@ ; CHECK-LABEL: and_nxv16i8_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.b -; CHECK-NEXT: and z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.b, p0/z, z2.b, #0 -; CHECK-NEXT: sel z0.b, p0, z0.b, z1.b +; CHECK-NEXT: and z1.b, p0/m, z1.b, z0.b +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1895,9 +1883,9 @@ ; CHECK-LABEL: or_nxv2i64_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.d -; CHECK-NEXT: orr z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.d, p0/z, z2.d, #0 -; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: orr z1.d, p0/m, z1.d, z0.d +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1910,9 +1898,9 @@ ; CHECK-LABEL: or_nxv4i32_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.s -; CHECK-NEXT: orr z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.s, p0/z, z2.s, #0 -; CHECK-NEXT: sel z0.s, p0, z0.s, z1.s +; CHECK-NEXT: orr z1.s, p0/m, z1.s, z0.s +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1925,9 +1913,9 @@ ; CHECK-LABEL: or_nxv8i16_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.h -; CHECK-NEXT: orr z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.h, p0/z, z2.h, #0 -; CHECK-NEXT: sel z0.h, p0, z0.h, z1.h +; CHECK-NEXT: orr z1.h, p0/m, z1.h, z0.h +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1940,9 +1928,9 @@ ; CHECK-LABEL: or_nxv16i8_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.b -; CHECK-NEXT: orr z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.b, p0/z, z2.b, #0 -; CHECK-NEXT: sel z0.b, p0, z0.b, z1.b +; CHECK-NEXT: orr z1.b, p0/m, z1.b, z0.b +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1955,9 +1943,9 @@ ; CHECK-LABEL: xor_nxv2i64_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.d -; CHECK-NEXT: eor z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.d, p0/z, z2.d, #0 -; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: eor z1.d, p0/m, z1.d, z0.d +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1970,9 +1958,9 @@ ; CHECK-LABEL: xor_nxv4i32_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.s -; CHECK-NEXT: eor z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.s, p0/z, z2.s, #0 -; CHECK-NEXT: sel z0.s, p0, z0.s, z1.s +; CHECK-NEXT: eor z1.s, p0/m, z1.s, z0.s +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -1985,9 +1973,9 @@ ; CHECK-LABEL: xor_nxv8i16_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.h -; CHECK-NEXT: eor z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.h, p0/z, z2.h, #0 -; CHECK-NEXT: sel z0.h, p0, z0.h, z1.h +; CHECK-NEXT: eor z1.h, p0/m, z1.h, z0.h +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer @@ -2000,9 +1988,9 @@ ; CHECK-LABEL: xor_nxv16i8_y: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.b -; CHECK-NEXT: eor z0.d, z0.d, z1.d ; CHECK-NEXT: cmpgt p0.b, p0/z, z2.b, #0 -; CHECK-NEXT: sel z0.b, p0, z0.b, z1.b +; CHECK-NEXT: eor z1.b, p0/m, z1.b, z0.b +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret entry: %c = icmp sgt %n, zeroinitializer