Index: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -260,7 +260,7 @@ def AArch64cnot_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_cnot node:$pt, node:$pg, node:$op)]>; def AArch64not_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_not node:$pt, node:$pg, node:$op)]>; -def AArch64fmul_m1 : EitherVSelectOrPassthruPatFrags; +def AArch64fmul_m1 : VSelectPredOrPassthruPatFrags; def AArch64fadd_m1 : PatFrags<(ops node:$pg, node:$op1, node:$op2), [ (int_aarch64_sve_fadd node:$pg, node:$op1, node:$op2), (vselect node:$pg, (AArch64fadd_p (SVEAllActive), node:$op1, node:$op2), node:$op1), @@ -443,10 +443,10 @@ def AArch64fmla_m1 : fma_patfrags; def AArch64fmls_m1 : fma_patfrags; -def AArch64smax_m1 : EitherVSelectOrPassthruPatFrags; -def AArch64umax_m1 : EitherVSelectOrPassthruPatFrags; -def AArch64smin_m1 : EitherVSelectOrPassthruPatFrags; -def AArch64umin_m1 : EitherVSelectOrPassthruPatFrags; +def AArch64smax_m1 : VSelectCommPredOrPassthruPatFrags; +def AArch64umax_m1 : VSelectCommPredOrPassthruPatFrags; +def AArch64smin_m1 : VSelectCommPredOrPassthruPatFrags; +def AArch64umin_m1 : VSelectCommPredOrPassthruPatFrags; let Predicates = [HasSVE] in { defm RDFFR_PPz : sve_int_rdffr_pred<0b0, "rdffr", int_aarch64_sve_rdffr_z>; Index: llvm/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -619,13 +619,22 @@ //===----------------------------------------------------------------------===// // Matches either an intrinsic, or a predicated operation with an all active predicate -class EitherVSelectOrPassthruPatFrags +class VSelectPredOrPassthruPatFrags : PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [ (intrinsic node:$Pg, node:$Op1, node:$Op2), (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1), ], [{ return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse(); }]>; +// Same as above with a commutative operation +class VSelectCommPredOrPassthruPatFrags +: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [ + (intrinsic node:$Pg, node:$Op1, node:$Op2), + (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1), + (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op2, node:$Op1), node:$Op1), + ], [{ + return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse(); + }]>; // // Pseudo -> Instruction mappings Index: llvm/test/CodeGen/AArch64/sve-min-max-pred.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-min-max-pred.ll +++ llvm/test/CodeGen/AArch64/sve-min-max-pred.ll @@ -190,9 +190,8 @@ define @smin_select_i64_c( %pg, %a, %b) { ; CHECK-LABEL: smin_select_i64_c: ; CHECK: // %bb.0: -; CHECK-NEXT: ptrue p1.d -; CHECK-NEXT: smin z0.d, p1/m, z0.d, z1.d -; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: smin z1.d, p0/m, z1.d, z0.d +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret %sel = call @llvm.smin.nxv2i64( %a, %b) %out = select %pg, %sel, %b @@ -202,9 +201,8 @@ define @smax_select_i64_c( %pg, %a, %b) { ; CHECK-LABEL: smax_select_i64_c: ; CHECK: // %bb.0: -; CHECK-NEXT: ptrue p1.d -; CHECK-NEXT: smax z0.d, p1/m, z0.d, z1.d -; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: smax z1.d, p0/m, z1.d, z0.d +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret %sel = call @llvm.smax.nxv2i64( %a, %b) %out = select %pg, %sel, %b @@ -214,9 +212,8 @@ define @umin_select_i64_c( %pg, %a, %b) { ; CHECK-LABEL: umin_select_i64_c: ; CHECK: // %bb.0: -; CHECK-NEXT: ptrue p1.d -; CHECK-NEXT: umin z0.d, p1/m, z0.d, z1.d -; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: umin z1.d, p0/m, z1.d, z0.d +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret %sel = call @llvm.umin.nxv2i64( %a, %b) %out = select %pg, %sel, %b @@ -226,9 +223,8 @@ define @umax_select_i64_c( %pg, %a, %b) { ; CHECK-LABEL: umax_select_i64_c: ; CHECK: // %bb.0: -; CHECK-NEXT: ptrue p1.d -; CHECK-NEXT: umax z0.d, p1/m, z0.d, z1.d -; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: umax z1.d, p0/m, z1.d, z0.d +; CHECK-NEXT: mov z0.d, z1.d ; CHECK-NEXT: ret %sel = call @llvm.umax.nxv2i64( %a, %b) %out = select %pg, %sel, %b