Skip to content

[LLVM][DAGCombiner][SVE] Fold vselect into merge_pasthru_op. #146917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25523,6 +25523,9 @@ static SDValue performVSelectCombine(SDNode *N, SelectionDAG &DAG) {
return SwapResult;

SDValue N0 = N->getOperand(0);
SDValue IfTrue = N->getOperand(1);
SDValue IfFalse = N->getOperand(2);
EVT ResVT = N->getValueType(0);
EVT CCVT = N0.getValueType();

if (isAllActivePredicate(DAG, N0))
Expand All @@ -25531,6 +25534,22 @@ static SDValue performVSelectCombine(SDNode *N, SelectionDAG &DAG) {
if (isAllInactivePredicate(N0))
return N->getOperand(2);

if (isMergePassthruOpcode(IfTrue.getOpcode()) && IfTrue.hasOneUse()) {
// vselect A, (merge_pasthru_op all_active, B,{Bn,} -), C
// vselect A, (merge_pasthru_op -, B,{Bn,} undef), C
// vselect A, (merge_pasthru_op A, B,{Bn,} -), C
// -> merge_pasthru_op A, B,{Bn,} C
if (isAllActivePredicate(DAG, IfTrue->getOperand(0)) ||
IfTrue->getOperand(IfTrue.getNumOperands() - 1).isUndef() ||
IfTrue->getOperand(0) == N0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any tests where isAllActivePredicate(DAG, IfTrue->getOperand(0)) is not true? From what I can tell, all of the affected tests in sve-merging-unary.ll were using ptrue before this change & still pass if I try removing the other conditions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whilst striving to extend the isel test coverage I've forgotten to test the DAG combine itself. I'll add tests to trigger the three cases.

SmallVector<SDValue, 4> Ops(IfTrue->op_values());
Ops[0] = N0;
Ops[IfTrue.getNumOperands() - 1] = IfFalse;

return DAG.getNode(IfTrue.getOpcode(), SDLoc(N), ResVT, Ops);
}
}

// Check for sign pattern (VSELECT setgt, iN lhs, -1, 1, -1) and transform
// into (OR (ASR lhs, N-1), 1), which requires less instructions for the
// supported types.
Expand Down Expand Up @@ -25570,14 +25589,11 @@ static SDValue performVSelectCombine(SDNode *N, SelectionDAG &DAG) {
CmpVT.getVectorElementType().isFloatingPoint())
return SDValue();

EVT ResVT = N->getValueType(0);
// Only combine when the result type is of the same size as the compared
// operands.
if (ResVT.getSizeInBits() != CmpVT.getSizeInBits())
return SDValue();

SDValue IfTrue = N->getOperand(1);
SDValue IfFalse = N->getOperand(2);
SetCC = DAG.getSetCC(SDLoc(N), CmpVT.changeVectorElementTypeToInteger(),
N0.getOperand(0), N0.getOperand(1),
cast<CondCodeSDNode>(N0.getOperand(2))->get());
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2445,14 +2445,23 @@ let Predicates = [HasSVE_or_SME] in {
defm FCVTZU_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1111111, "fcvtzu", ZPR64, ZPR64, null_frag, AArch64fcvtzu_mt, nxv2i64, nxv2i1, nxv2f64, ElementSizeD>;

//These patterns exist to improve the code quality of conversions on unpacked types.
def : Pat<(nxv2f32 (AArch64fcvte_mt nxv2i1:$Pg, nxv2f16:$Zs, nxv2f32:$Zd)),
(FCVT_ZPmZ_HtoS ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
def : Pat<(nxv2f32 (AArch64fcvte_mt (nxv2i1 (SVEAllActive:$Pg)), nxv2f16:$Zs, nxv2f32:$Zd)),
(FCVT_ZPmZ_HtoS_UNDEF ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;

// FP_ROUND has an additional 'precise' flag which indicates the type of rounding.
// This is ignored by the pattern below where it is matched by (i64 timm0_1)
def : Pat<(nxv2f16 (AArch64fcvtr_mt nxv2i1:$Pg, nxv2f32:$Zs, (i64 timm0_1), nxv2f16:$Zd)),
(FCVT_ZPmZ_StoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
def : Pat<(nxv2f16 (AArch64fcvtr_mt (nxv2i1 (SVEAllActive:$Pg)), nxv2f32:$Zs, (i64 timm0_1), nxv2f16:$Zd)),
(FCVT_ZPmZ_StoH_UNDEF ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;

def : Pat<(nxv4f32 (AArch64fcvte_mt nxv4i1:$Pg, nxv4bf16:$Zs, nxv4f32:$Zd)),
(SEL_ZPZZ_S $Pg, (LSL_ZZI_S $Zs, (i32 16)), $Zd)>;
def : Pat<(nxv2f32 (AArch64fcvte_mt nxv2i1:$Pg, nxv2bf16:$Zs, nxv2f32:$Zd)),
(SEL_ZPZZ_D $Pg, (LSL_ZZI_S $Zs, (i32 16)), $Zd)>;

def : Pat<(nxv4f32 (AArch64fcvte_mt (SVEAnyPredicate), nxv4bf16:$op, undef)),
(LSL_ZZI_S $op, (i32 16))>;
def : Pat<(nxv2f32 (AArch64fcvte_mt (SVEAnyPredicate), nxv2bf16:$op, undef)),
Expand Down
Loading
Loading