[llvm] [RISCV] Recurse on second operand of two operand shuffles (PR #79197)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 24 04:37:20 PST 2024
================
@@ -5046,50 +5038,13 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
return convertFromScalableVector(VT, Gather, DAG, Subtarget);
}
- // Translate the gather index we computed above (and possibly swapped)
- // back to a shuffle mask. This step should disappear once we complete
- // the migration to recursive design.
- SmallVector<int> ShuffleMaskLHS;
- ShuffleMaskLHS.reserve(GatherIndicesLHS.size());
- for (SDValue GatherIndex : GatherIndicesLHS) {
- if (GatherIndex.isUndef()) {
- ShuffleMaskLHS.push_back(-1);
- continue;
- }
- auto *IdxC = cast<ConstantSDNode>(GatherIndex);
- ShuffleMaskLHS.push_back(IdxC->getZExtValue());
- }
-
- // Recursively invoke lowering for the LHS as if there were no RHS.
- // This allows us to leverage all of our single source permute tricks.
- SDValue Gather =
- DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT), ShuffleMaskLHS);
- Gather = convertToScalableVector(ContainerVT, Gather, DAG, Subtarget);
-
- // Blend in second vector source with an additional vrgather.
- V2 = convertToScalableVector(ContainerVT, V2, DAG, Subtarget);
-
- MVT MaskContainerVT = ContainerVT.changeVectorElementType(MVT::i1);
- SelectMask =
- convertToScalableVector(MaskContainerVT, SelectMask, DAG, Subtarget);
-
- // If only one index is used, we can use a "splat" vrgather.
- // TODO: We can splat the most-common index and fix-up any stragglers, if
- // that's beneficial.
- if (RHSIndexCounts.size() == 1) {
- int SplatIndex = RHSIndexCounts.begin()->getFirst();
- Gather = DAG.getNode(GatherVXOpc, DL, ContainerVT, V2,
- DAG.getConstant(SplatIndex, DL, XLenVT), Gather,
- SelectMask, VL);
- } else {
- SDValue RHSIndices = DAG.getBuildVector(IndexVT, DL, GatherIndicesRHS);
- RHSIndices =
- convertToScalableVector(IndexContainerVT, RHSIndices, DAG, Subtarget);
- Gather = DAG.getNode(GatherVVOpc, DL, ContainerVT, V2, RHSIndices, Gather,
- SelectMask, VL);
- }
-
- return convertFromScalableVector(VT, Gather, DAG, Subtarget);
+ // Recursively invoke lowering for each operand if we had two
+ // independent single source permutes, and then combine the result via a
+ // vselect. Note that the vselect will likely be folded back into the
+ // second permute (vrgather, or other) by the post-isel combine.
+ V1 = DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT), ShuffleMaskLHS);
+ V2 = DAG.getVectorShuffle(VT, DL, V2, DAG.getUNDEF(VT), ShuffleMaskRHS);
+ return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, V2, V1);
----------------
lukel97 wrote:
An aside, do you have a plan for handling cases where one shuffle is an identity op? e.g.
```llvm
%shuffle = shufflevector <4 x i64> %0, <4 x i64> %1, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
```
After this patch we get
```asm
vsetivli zero, 4, e64, m1, ta, ma
vmv.v.i v0, 12
vslidedown.vi v8, v8, 2
vmerge.vvm v8, v8, v9, v0
```
But we can do this one slidedown:
```asm
vsetivli zero, 2, e64, m1, ta, ma
vslidedown.vi v9, v8, 2
```
https://github.com/llvm/llvm-project/pull/79197
More information about the llvm-commits
mailing list