Index: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ 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 Index: llvm/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -635,6 +635,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 Index: llvm/test/CodeGen/AArch64/sve-pred-selectop2.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-pred-selectop2.ll +++ llvm/test/CodeGen/AArch64/sve-pred-selectop2.ll @@ -527,9 +527,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 @@ -542,9 +541,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 @@ -557,9 +555,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 @@ -572,9 +569,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 @@ -587,9 +583,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 @@ -602,9 +597,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 @@ -617,9 +611,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 @@ -632,9 +625,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 @@ -647,9 +639,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 @@ -662,9 +653,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 @@ -677,9 +667,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 @@ -692,9 +681,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 @@ -1827,9 +1815,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 @@ -1842,9 +1830,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 @@ -1857,9 +1845,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 @@ -1872,9 +1860,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 @@ -1887,9 +1875,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 @@ -1902,9 +1890,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 @@ -1917,9 +1905,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 @@ -1932,9 +1920,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 @@ -1947,9 +1935,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 @@ -1962,9 +1950,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 @@ -1977,9 +1965,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 @@ -1992,9 +1980,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