[llvm] e2bb977 - [LegalizeTypes] Support widen result for VECTOR_REVERSE.
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 29 19:01:59 PDT 2022
Author: wanglian
Date: 2022-08-30T10:01:26+08:00
New Revision: e2bb9774b173487cebec9cb8b0568c3d9b4d55f8
URL: https://github.com/llvm/llvm-project/commit/e2bb9774b173487cebec9cb8b0568c3d9b4d55f8
DIFF: https://github.com/llvm/llvm-project/commit/e2bb9774b173487cebec9cb8b0568c3d9b4d55f8.diff
LOG: [LegalizeTypes] Support widen result for VECTOR_REVERSE.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D132359
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
llvm/test/CodeGen/RISCV/rvv/named-vector-shuffle-reverse.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index bfad91ca4822f..04bff24f5fcb6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -962,6 +962,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
SDValue WidenVecRes_STRICT_FSETCC(SDNode* N);
SDValue WidenVecRes_UNDEF(SDNode *N);
SDValue WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N);
+ SDValue WidenVecRes_VECTOR_REVERSE(SDNode *N);
SDValue WidenVecRes_Ternary(SDNode *N);
SDValue WidenVecRes_Binary(SDNode *N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 2c4068865ad00..058ed3cd922b9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -3881,6 +3881,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::VP_GATHER:
Res = WidenVecRes_VP_GATHER(cast<VPGatherSDNode>(N));
break;
+ case ISD::VECTOR_REVERSE:
+ Res = WidenVecRes_VECTOR_REVERSE(N);
+ break;
case ISD::ADD: case ISD::VP_ADD:
case ISD::AND: case ISD::VP_AND:
@@ -5533,6 +5536,61 @@ SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) {
return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
}
+SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_REVERSE(SDNode *N) {
+ EVT VT = N->getValueType(0);
+ EVT EltVT = VT.getVectorElementType();
+ SDLoc dl(N);
+
+ EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
+ SDValue OpValue = GetWidenedVector(N->getOperand(0));
+ assert(WidenVT == OpValue.getValueType() && "Unexpected widened vector type");
+
+ SDValue ReverseVal = DAG.getNode(ISD::VECTOR_REVERSE, dl, WidenVT, OpValue);
+ unsigned WidenNumElts = WidenVT.getVectorMinNumElements();
+ unsigned VTNumElts = VT.getVectorMinNumElements();
+ unsigned IdxVal = WidenNumElts - VTNumElts;
+
+ if (VT.isScalableVector()) {
+ // Try to split the 'Widen ReverseVal' into smaller extracts and concat the
+ // results together, e.g.(nxv6i64 -> nxv8i64)
+ // nxv8i64 vector_reverse
+ // <->
+ // nxv8i64 concat(
+ // nxv2i64 extract_subvector(nxv8i64, 2)
+ // nxv2i64 extract_subvector(nxv8i64, 4)
+ // nxv2i64 extract_subvector(nxv8i64, 6)
+ // nxv2i64 undef)
+
+ unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
+ EVT PartVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
+ ElementCount::getScalable(GCD));
+ assert((IdxVal % GCD) == 0 && "Expected Idx to be a multiple of the broken "
+ "down type's element count");
+ SmallVector<SDValue> Parts;
+ unsigned i = 0;
+ for (; i < VTNumElts / GCD; ++i)
+ Parts.push_back(
+ DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, PartVT, ReverseVal,
+ DAG.getVectorIdxConstant(IdxVal + i * GCD, dl)));
+ for (; i < WidenNumElts / GCD; ++i)
+ Parts.push_back(DAG.getUNDEF(PartVT));
+
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Parts);
+ }
+
+ // Use VECTOR_SHUFFLE to combine new vector from 'ReverseVal' for
+ // fixed-vectors.
+ SmallVector<int, 16> Mask;
+ for (unsigned i = 0; i != VTNumElts; ++i) {
+ Mask.push_back(IdxVal + i);
+ }
+ for (unsigned i = VTNumElts; i != WidenNumElts; ++i)
+ Mask.push_back(-1);
+
+ return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
+ Mask);
+}
+
SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) {
assert(N->getValueType(0).isVector() &&
N->getOperand(0).getValueType().isVector() &&
diff --git a/llvm/test/CodeGen/RISCV/rvv/named-vector-shuffle-reverse.ll b/llvm/test/CodeGen/RISCV/rvv/named-vector-shuffle-reverse.ll
index 618537b5281fe..85616c21fedba 100644
--- a/llvm/test/CodeGen/RISCV/rvv/named-vector-shuffle-reverse.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/named-vector-shuffle-reverse.ll
@@ -1630,6 +1630,77 @@ define <vscale x 8 x double> @reverse_nxv8f64(<vscale x 8 x double> %a) {
ret <vscale x 8 x double> %res
}
+; Test widen reverse vector
+
+define <vscale x 3 x i64> @reverse_nxv3i64(<vscale x 3 x i64> %a) {
+; CHECK-LABEL: reverse_nxv3i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: csrr a0, vlenb
+; CHECK-NEXT: srli a0, a0, 1
+; CHECK-NEXT: addi a0, a0, -1
+; CHECK-NEXT: vsetvli a1, zero, e64, m4, ta, mu
+; CHECK-NEXT: vid.v v12
+; CHECK-NEXT: vrsub.vx v12, v12, a0
+; CHECK-NEXT: vrgather.vv v16, v8, v12
+; CHECK-NEXT: vmv1r.v v8, v17
+; CHECK-NEXT: vmv1r.v v9, v18
+; CHECK-NEXT: vmv1r.v v10, v19
+; CHECK-NEXT: ret
+ %res = call <vscale x 3 x i64> @llvm.experimental.vector.reverse.nxv3i64(<vscale x 3 x i64> %a)
+ ret <vscale x 3 x i64> %res
+}
+
+define <vscale x 6 x i64> @reverse_nxv6i64(<vscale x 6 x i64> %a) {
+; CHECK-LABEL: reverse_nxv6i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: csrr a0, vlenb
+; CHECK-NEXT: addi a0, a0, -1
+; CHECK-NEXT: vsetvli a1, zero, e64, m8, ta, mu
+; CHECK-NEXT: vid.v v16
+; CHECK-NEXT: vrsub.vx v16, v16, a0
+; CHECK-NEXT: vrgather.vv v24, v8, v16
+; CHECK-NEXT: vmv2r.v v8, v26
+; CHECK-NEXT: vmv2r.v v10, v28
+; CHECK-NEXT: vmv2r.v v12, v30
+; CHECK-NEXT: ret
+ %res = call <vscale x 6 x i64> @llvm.experimental.vector.reverse.nxv6i64(<vscale x 6 x i64> %a)
+ ret <vscale x 6 x i64> %res
+}
+
+define <vscale x 12 x i64> @reverse_nxv12i64(<vscale x 12 x i64> %a) {
+; CHECK-LABEL: reverse_nxv12i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: addi sp, sp, -64
+; CHECK-NEXT: .cfi_def_cfa_offset 64
+; CHECK-NEXT: addi s0, sp, 64
+; CHECK-NEXT: .cfi_def_cfa s0, 0
+; CHECK-NEXT: csrr a0, vlenb
+; CHECK-NEXT: slli a0, a0, 4
+; CHECK-NEXT: sub sp, sp, a0
+; CHECK-NEXT: andi sp, sp, -64
+; CHECK-NEXT: csrr a0, vlenb
+; CHECK-NEXT: addi a1, a0, -1
+; CHECK-NEXT: vsetvli a2, zero, e64, m8, ta, mu
+; CHECK-NEXT: vid.v v24
+; CHECK-NEXT: vrsub.vx v24, v24, a1
+; CHECK-NEXT: vrgather.vv v0, v16, v24
+; CHECK-NEXT: vmv4r.v v16, v4
+; CHECK-NEXT: vrgather.vv v0, v8, v24
+; CHECK-NEXT: vmv4r.v v20, v0
+; CHECK-NEXT: slli a0, a0, 3
+; CHECK-NEXT: addi a1, sp, 64
+; CHECK-NEXT: add a0, a1, a0
+; CHECK-NEXT: vs4r.v v4, (a0)
+; CHECK-NEXT: vs8r.v v16, (a1)
+; CHECK-NEXT: vl8re64.v v16, (a0)
+; CHECK-NEXT: vl8re64.v v8, (a1)
+; CHECK-NEXT: addi sp, s0, -64
+; CHECK-NEXT: addi sp, sp, 64
+; CHECK-NEXT: ret
+ %res = call <vscale x 12 x i64> @llvm.experimental.vector.reverse.nxv12i64(<vscale x 12 x i64> %a)
+ ret <vscale x 12 x i64> %res
+}
+
declare <vscale x 2 x i1> @llvm.experimental.vector.reverse.nxv2i1(<vscale x 2 x i1>)
declare <vscale x 4 x i1> @llvm.experimental.vector.reverse.nxv4i1(<vscale x 4 x i1>)
declare <vscale x 8 x i1> @llvm.experimental.vector.reverse.nxv8i1(<vscale x 8 x i1>)
@@ -1673,3 +1744,6 @@ declare <vscale x 1 x double> @llvm.experimental.vector.reverse.nxv1f64(<vscale
declare <vscale x 2 x double> @llvm.experimental.vector.reverse.nxv2f64(<vscale x 2 x double>)
declare <vscale x 4 x double> @llvm.experimental.vector.reverse.nxv4f64(<vscale x 4 x double>)
declare <vscale x 8 x double> @llvm.experimental.vector.reverse.nxv8f64(<vscale x 8 x double>)
+declare <vscale x 3 x i64> @llvm.experimental.vector.reverse.nxv3i64(<vscale x 3 x i64>)
+declare <vscale x 6 x i64> @llvm.experimental.vector.reverse.nxv6i64(<vscale x 6 x i64>)
+declare <vscale x 12 x i64> @llvm.experimental.vector.reverse.nxv12i64(<vscale x 12 x i64>)
More information about the llvm-commits
mailing list