[llvm] [RISCV] Combine build_vector of extract_vector_elts to vector_shuffle (PR #80883)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 7 10:49:27 PST 2024
================
@@ -14933,11 +14933,68 @@ static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
return tryFoldSelectIntoOp(N, DAG, FalseVal, TrueVal, /*Swapped*/true);
}
-/// If we have a build_vector where each lane is binop X, C, where C
-/// is a constant (but not necessarily the same constant on all lanes),
-/// form binop (build_vector x1, x2, ...), (build_vector c1, c2, c3, ..).
-/// We assume that materializing a constant build vector will be no more
-/// expensive that performing O(n) binops.
+/// Canonicalize
+///
+/// (build_vector (extract_vector_elt v, i0),
+/// (extract_vector_elt v, i1),
+/// (extract_vector_elt v, i2),
+/// (extract_vector_elt v, i3))
+///
+/// to
+///
+/// (vector_shuffle<i0, i1, i2, i3> v, undef)
+///
+/// shufflevectors may be lowered to the build_vector pattern above if the
+/// vector types don't match, so try and recover the shuffle to avoid
+/// scalarization.
+///
+/// Note that this combine exists in a similar form in DAGCombiner.cpp, but it
+/// depends on extract_subvector being cheap. On RISC-V we always want to use
+/// the vector_shuffle form, so we perform it unconditionally here.
+static SDValue combineBuildVectorToShuffle(SDNode *N, SelectionDAG &DAG,
+ const RISCVTargetLowering &TLI) {
+ EVT VT = N->getValueType(0);
+ SDLoc DL(N);
+ if (!TLI.isTypeLegal(VT))
+ return SDValue();
+
+ SDValue ExtractVec;
+ SmallVector<int> Mask(N->getNumOperands(), -1);
+ for (auto [i, Op] : enumerate(N->op_values())) {
+ if (Op.isUndef())
+ continue;
+ if (Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
+ return SDValue();
+ if (!isa<ConstantSDNode>(Op.getOperand(1)))
+ return SDValue();
+ if (!ExtractVec) {
+ ExtractVec = Op.getOperand(0);
+ Mask[i] = Op.getConstantOperandVal(1);
+ continue;
+ }
+ if (Op.getOperand(0) != ExtractVec)
+ return SDValue();
+ Mask[i] = Op.getConstantOperandVal(1);
+ }
+
+ EVT ExtractVT = ExtractVec.getValueType();
+ if (ExtractVT.isScalableVector())
----------------
preames wrote:
You probably should check that ExtractVT is legal here.
https://github.com/llvm/llvm-project/pull/80883
More information about the llvm-commits
mailing list