diff options
author | Philip Reames <preames@rivosinc.com> | 2023-08-07 07:49:15 -0700 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2023-08-07 07:54:29 -0700 |
commit | 47fe3b3b9a2649aba2ccbab91e530fbd247f8280 (patch) | |
tree | 738c2ba5fac44cfba149c9eae0d45cbb9e642a44 /llvm/lib | |
parent | 7eba3e58d5a383e47973c3d3945277f0115c86f3 (diff) | |
download | llvm-47fe3b3b9a2649aba2ccbab91e530fbd247f8280.zip llvm-47fe3b3b9a2649aba2ccbab91e530fbd247f8280.tar.gz llvm-47fe3b3b9a2649aba2ccbab91e530fbd247f8280.tar.bz2 |
[RISCV] Use v(f)slide1down for build_vector with dominant values
If we have a dominant value, we can still use a v(f)slide1down to handle the last value in the vector if that value is neither undef nor the dominant value.
Note that we can extend this idea to any tail of elements, but that's ends up being a near complete merge of the v(f)slide1down insert path, and requires a bit more untangling on profitability heuristics first.
Differential Revision: https://reviews.llvm.org/D157120
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 3a58185..a1ad973 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3014,7 +3014,10 @@ static SDValue lowerBuildVectorViaDominantValues(SDValue Op, SelectionDAG &DAG, MVT VT = Op.getSimpleValueType(); assert(VT.isFixedLengthVector() && "Unexpected vector!"); + MVT ContainerVT = getContainerForFixedLengthVector(DAG, VT, Subtarget); + SDLoc DL(Op); + auto [Mask, VL] = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget); MVT XLenVT = Subtarget.getXLenVT(); unsigned NumElts = Op.getNumOperands(); @@ -3065,6 +3068,24 @@ static SDValue lowerBuildVectorViaDominantValues(SDValue Op, SelectionDAG &DAG, SDValue Vec = DAG.getSplatBuildVector(VT, DL, DominantValue); DenseSet<SDValue> Processed{DominantValue}; + + // We can handle an insert into the last element (of a splat) via + // v(f)slide1down. This is slightly better than the vslideup insert + // lowering as it avoids the need for a vector group temporary. It + // is also better than using vmerge.vx as it avoids the need to + // materialize the mask in a vector register. + if (SDValue LastOp = Op->getOperand(Op->getNumOperands() - 1); + !LastOp.isUndef() && ValueCounts[LastOp] == 1 && + LastOp != DominantValue) { + Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget); + auto OpCode = + VT.isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL; + Vec = DAG.getNode(OpCode, DL, ContainerVT, DAG.getUNDEF(ContainerVT), Vec, + LastOp, Mask, VL); + Vec = convertFromScalableVector(VT, Vec, DAG, Subtarget); + Processed.insert(LastOp); + } + MVT SelMaskTy = VT.changeVectorElementType(MVT::i1); for (const auto &OpIdx : enumerate(Op->ops())) { const SDValue &V = OpIdx.value(); |