[llvm] [AArch64] Avoid GPR trip when moving truncated i32 vector elements (PR #114541)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 19 07:24:33 PST 2024
================
@@ -20735,17 +20735,53 @@ static SDValue performBuildVectorCombine(SDNode *N,
return SDValue();
}
-static SDValue performTruncateCombine(SDNode *N,
- SelectionDAG &DAG) {
+static SDValue performTruncateCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ SDLoc DL(N);
EVT VT = N->getValueType(0);
SDValue N0 = N->getOperand(0);
if (VT.isFixedLengthVector() && VT.is64BitVector() && N0.hasOneUse() &&
N0.getOpcode() == AArch64ISD::DUP) {
SDValue Op = N0.getOperand(0);
if (VT.getScalarType() == MVT::i32 &&
N0.getOperand(0).getValueType().getScalarType() == MVT::i64)
- Op = DAG.getNode(ISD::TRUNCATE, SDLoc(N), MVT::i32, Op);
- return DAG.getNode(N0.getOpcode(), SDLoc(N), VT, Op);
+ Op = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op);
+ return DAG.getNode(N0.getOpcode(), DL, VT, Op);
+ }
+
+ // Performing the following combine produces a preferable form for ISEL.
+ // i32 (trunc (extract Vi64, idx)) -> i32 (extract (nvcast Vi32), idx*2))
+ if (DCI.isAfterLegalizeDAG() && N0.getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
+ SDValue Op = N0.getOperand(0);
+ SDValue ExtractIndexNode = N0.getOperand(1);
+ if (!isa<ConstantSDNode>(ExtractIndexNode))
+ return SDValue();
+
+ // For a legal DAG, EXTRACT_VECTOR_ELT can only have produced an i32 or i64.
+ // So we can only expect: i32 (trunc (i64 (extract Vi64, idx))).
+ assert((VT == MVT::i32 && N0.getValueType() == MVT::i64) &&
+ "Unexpected legalisation result!");
+
+ EVT SrcVectorType = Op.getValueType();
+ // We also assume that SrcVectorType cannot be a V64 (see
+ // LowerEXTRACT_VECTOR_ELT).
+ assert((SrcVectorType.getScalarType() == MVT::i64 &&
+ SrcVectorType != MVT::v1i64) &&
+ "Unexpected legalisation result!");
+
+ // If the i64 we are extacting has uses other than this truncation, the
+ // upper half of this value must still be live so we prefer to extract it
+ // all at once.
+ if (!N0.hasOneUse())
+ return SDValue();
----------------
paulwalker-arm wrote:
This is generally common sense so I'd just add the `N0.hasOneUse()` to the entry if condition.
https://github.com/llvm/llvm-project/pull/114541
More information about the llvm-commits
mailing list