[llvm] [RISCV] Fix incorrect fixed vector lowering for VECTOR_DEINTERLEAVE (PR #207254)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 2 13:46:29 PDT 2026
================
@@ -13163,6 +13148,83 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op,
return DAG.getMergeValues(Res, DL);
}
+ // Convert to scalable vectors.
+ if (VecVT.isFixedLengthVector()) {
+ ElementCount OrigEC = VecVT.getVectorElementCount();
+ // Note that we cannot just convert individual operands to scalable vectors
+ // and call it a day: as scalable vector container is always equal or
+ // larger than the fixed vector subject, in the case where it is larger
+ // than fixed vector, this approach will create "padded" lanes in the
+ // conceptually concated vector created by VECTOR_DEINTERLEAVE per its
+ // semantics.
+
+ // First, concat operands into a larger (fixed) vector.
+ // There are two ways to do this: insert each operands into a larger
+ // (legal) vector one by one, or concat_vectors with additional
+ // operands to pad to legal type. The first way seems to lead to
+ // worse codegen primarily because we don't run DAGCombiner to
+ // simplify stuffs before some of the insert_subvector got
+ // lower into vslideup/down prematurely.
+ EVT ConcatVecEVT = EVT(VecVT).changeVectorElementCount(
+ *DAG.getContext(), OrigEC.multiplyCoefficientBy(Factor));
+ SmallVector<SDValue, 8> ConcatOps(Op->op_begin(), Op->op_end());
+ MVT ConcatVecVT;
+ if (!isTypeLegal(ConcatVecEVT)) {
+ // SplitVector should already be handled above.
+ assert(getTypeAction(*DAG.getContext(), ConcatVecEVT) ==
+ TargetLowering::TypeWidenVector);
+ ConcatVecVT =
+ getTypeToTransformTo(*DAG.getContext(), ConcatVecEVT).getSimpleVT();
+ ElementCount WidenedConcatEC = ConcatVecVT.getVectorElementCount();
+ // Both OrigEC and WidenedConcatEC are both derived from legal fixed
+ // vector types. A legal fixed vector's element count is always power of
+ // two, so WidenedConcatEC will always be a multiple of OrigEC.
+ assert(WidenedConcatEC.hasKnownScalarFactor(OrigEC));
+ unsigned NumTotalConcatOps = WidenedConcatEC.getKnownScalarFactor(OrigEC);
+ assert(NumTotalConcatOps > Factor);
+ ConcatOps.append(NumTotalConcatOps - Factor, DAG.getUNDEF(VecVT));
+ } else {
+ ConcatVecVT = ConcatVecEVT.getSimpleVT();
+ }
+
+ SDValue ConcatVec =
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVecVT, ConcatOps);
+ MVT ConcatContainerVT = getContainerForFixedLengthVector(ConcatVecVT);
+ ElementCount ConcatContainerEC = ConcatContainerVT.getVectorElementCount();
+ ConcatVec =
+ convertToScalableVector(ConcatContainerVT, ConcatVec, DAG, Subtarget);
+
+ MVT ContainerVT = getContainerForFixedLengthVector(VecVT);
+ ElementCount ContainerEC = ContainerVT.getVectorElementCount();
+
+ SmallVector<SDValue, 8> Ops(Factor);
+ // Then, we extract the new scalable sub-vectors.
+ for (unsigned i = 0U; i < Factor; ++i) {
+ ElementCount Idx = ContainerEC.multiplyCoefficientBy(i);
+ // Index might be out-of-bound. This usually happens on large
+ // VLEN where a single or a few VR registers is enough to caputre
----------------
topperc wrote:
```suggestion
// VLEN where a single or a few VR registers is enough to capture
```
https://github.com/llvm/llvm-project/pull/207254
More information about the llvm-commits
mailing list