Skip to content

Commit 42b4a62

Browse files
[DAGCombine] Prevent illegal ISD::SPLAT_VECTOR operations post legalisation.
When triggered during operation legalisation the affected combine generates a splat_vector that when custom lowered for SVE fixed length code generation, results in the original precombine sequence and thus we enter a legalisation/combine hang. NOTE: The patch contains no tests because I observed this issue only when combined with other work that might never become public. The current way AArch64 lowers ISD::SPLAT_VECTOR meant a specific test was not possible so I'm hoping the DAGCombiner fix can be seen as obvious. The AArch64ISelLowering change is requirted to maintain existing code quality. Differential Revision: https://reviews.llvm.org/D120735
1 parent fb42e55 commit 42b4a62

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21260,7 +21260,8 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode *N) {
2126021260
// ty1 extract_vector(ty2 splat(V))) -> ty1 splat(V)
2126121261
if (V.getOpcode() == ISD::SPLAT_VECTOR)
2126221262
if (DAG.isConstantValueOfAnyType(V.getOperand(0)) || V.hasOneUse())
21263-
return DAG.getSplatVector(NVT, SDLoc(N), V.getOperand(0));
21263+
if (!LegalOperations || TLI.isOperationLegal(ISD::SPLAT_VECTOR, NVT))
21264+
return DAG.getSplatVector(NVT, SDLoc(N), V.getOperand(0));
2126421265

2126521266
// Try to move vector bitcast after extract_subv by scaling extraction index:
2126621267
// extract_subv (bitcast X), Index --> bitcast (extract_subv X, Index')

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
871871
setTargetDAGCombine(ISD::VECTOR_SPLICE);
872872
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
873873
setTargetDAGCombine(ISD::CONCAT_VECTORS);
874+
setTargetDAGCombine(ISD::EXTRACT_SUBVECTOR);
874875
setTargetDAGCombine(ISD::INSERT_SUBVECTOR);
875876
setTargetDAGCombine(ISD::STORE);
876877
if (Subtarget->supportsAddressTopByteIgnored())
@@ -14472,6 +14473,29 @@ static SDValue performConcatVectorsCombine(SDNode *N,
1447214473
RHS));
1447314474
}
1447414475

14476+
static SDValue
14477+
performExtractSubvectorCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
14478+
SelectionDAG &DAG) {
14479+
if (DCI.isBeforeLegalizeOps())
14480+
return SDValue();
14481+
14482+
EVT VT = N->getValueType(0);
14483+
if (!VT.isScalableVector() || VT.getVectorElementType() != MVT::i1)
14484+
return SDValue();
14485+
14486+
SDValue V = N->getOperand(0);
14487+
14488+
// NOTE: This combine exists in DAGCombiner, but that version's legality check
14489+
// blocks this combine because the non-const case requires custom lowering.
14490+
//
14491+
// ty1 extract_vector(ty2 splat(const))) -> ty1 splat(const)
14492+
if (V.getOpcode() == ISD::SPLAT_VECTOR)
14493+
if (isa<ConstantSDNode>(V.getOperand(0)))
14494+
return DAG.getNode(ISD::SPLAT_VECTOR, SDLoc(N), VT, V.getOperand(0));
14495+
14496+
return SDValue();
14497+
}
14498+
1447514499
static SDValue
1447614500
performInsertSubvectorCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
1447714501
SelectionDAG &DAG) {
@@ -18181,6 +18205,8 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
1818118205
return performSignExtendInRegCombine(N, DCI, DAG);
1818218206
case ISD::CONCAT_VECTORS:
1818318207
return performConcatVectorsCombine(N, DCI, DAG);
18208+
case ISD::EXTRACT_SUBVECTOR:
18209+
return performExtractSubvectorCombine(N, DCI, DAG);
1818418210
case ISD::INSERT_SUBVECTOR:
1818518211
return performInsertSubvectorCombine(N, DCI, DAG);
1818618212
case ISD::SELECT:

0 commit comments

Comments
 (0)