[llvm] 9e62c91 - [RISCV] Initial support for insert/extract subvector
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 11 14:36:07 PST 2021
Author: ShihPo Hung
Date: 2021-02-11T14:35:49-08:00
New Revision: 9e62c9146d2c125a1abda594add70ed66008e372
URL: https://github.com/llvm/llvm-project/commit/9e62c9146d2c125a1abda594add70ed66008e372
DIFF: https://github.com/llvm/llvm-project/commit/9e62c9146d2c125a1abda594add70ed66008e372.diff
LOG: [RISCV] Initial support for insert/extract subvector
This patch handles cast-like insert_subvector & extract_subvector
in which case:
1. index starts from 0.
2. inserting a fixed-width vector into a scalable vector,
or extracting a fixed-width vector from a scalable vector.
Reviewed By: craig.topper, frasercrmck
Differential Revision: https://reviews.llvm.org/D96352
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index adac52672466..62fe6460a7a4 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -71,6 +71,24 @@ static RISCVVLMUL getLMUL(MVT VT) {
}
}
+static unsigned getRegClassIDForLMUL(RISCVVLMUL LMul) {
+ switch (LMul) {
+ default:
+ llvm_unreachable("Invalid LMUL.");
+ case RISCVVLMUL::LMUL_F8:
+ case RISCVVLMUL::LMUL_F4:
+ case RISCVVLMUL::LMUL_F2:
+ case RISCVVLMUL::LMUL_1:
+ return RISCV::VRRegClassID;
+ case RISCVVLMUL::LMUL_2:
+ return RISCV::VRM2RegClassID;
+ case RISCVVLMUL::LMUL_4:
+ return RISCV::VRM4RegClassID;
+ case RISCVVLMUL::LMUL_8:
+ return RISCV::VRM8RegClassID;
+ }
+}
+
static unsigned getSubregIndexByMVT(MVT VT, unsigned Index) {
RISCVVLMUL LMUL = getLMUL(VT);
if (LMUL == RISCVVLMUL::LMUL_F8 || LMUL == RISCVVLMUL::LMUL_F4 ||
@@ -823,6 +841,48 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
}
break;
}
+ case ISD::INSERT_SUBVECTOR: {
+ // Bail when not a "cast" like insert_subvector.
+ if (Node->getConstantOperandVal(2) != 0)
+ break;
+ if (!Node->getOperand(0).isUndef())
+ break;
+
+ // Bail when normal isel should do the job.
+ EVT InVT = Node->getOperand(1).getValueType();
+ if (VT.isFixedLengthVector() || InVT.isScalableVector())
+ break;
+
+ SDValue V = Node->getOperand(1);
+ SDLoc DL(V);
+ unsigned RegClassID = getRegClassIDForLMUL(getLMUL(VT));
+ SDValue RC =
+ CurDAG->getTargetConstant(RegClassID, DL, Subtarget->getXLenVT());
+ SDNode *NewNode =
+ CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
+ ReplaceNode(Node, NewNode);
+ return;
+ }
+ case ISD::EXTRACT_SUBVECTOR: {
+ // Bail when not a "cast" like extract_subvector.
+ if (Node->getConstantOperandVal(1) != 0)
+ break;
+
+ // Bail when normal isel can do the job.
+ EVT InVT = Node->getOperand(0).getValueType();
+ if (VT.isScalableVector() || InVT.isFixedLengthVector())
+ break;
+
+ SDValue V = Node->getOperand(0);
+ SDLoc DL(V);
+ unsigned RegClassID = getRegClassIDForLMUL(getLMUL(InVT.getSimpleVT()));
+ SDValue RC =
+ CurDAG->getTargetConstant(RegClassID, DL, Subtarget->getXLenVT());
+ SDNode *NewNode =
+ CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
+ ReplaceNode(Node, NewNode);
+ return;
+ }
}
// Select the default instruction.
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
index 2766cca57fc9..e5920d64af1d 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
@@ -3435,3 +3435,57 @@ define void @urem_v4i64(<4 x i64>* %x, <4 x i64>* %y) {
store <4 x i64> %c, <4 x i64>* %x
ret void
}
+
+define void @extract_v4i64(<4 x i64>* %x, <4 x i64>* %y) {
+; LMULMAX2-LABEL: extract_v4i64:
+; LMULMAX2: # %bb.0:
+; LMULMAX2-NEXT: addi a2, zero, 4
+; LMULMAX2-NEXT: vsetvli a3, a2, e64,m2,ta,mu
+; LMULMAX2-NEXT: vle64.v v26, (a0)
+; LMULMAX2-NEXT: vle64.v v28, (a1)
+; LMULMAX2-NEXT: vsetvli a1, a2, e64,m2,ta,mu
+; LMULMAX2-NEXT: vadd.vv v26, v26, v28
+; LMULMAX2-NEXT: vse64.v v26, (a0)
+; LMULMAX2-NEXT: ret
+;
+; LMULMAX1-RV32-LABEL: extract_v4i64:
+; LMULMAX1-RV32: # %bb.0:
+; LMULMAX1-RV32-NEXT: addi a2, zero, 2
+; LMULMAX1-RV32-NEXT: vsetvli a3, a2, e64,m1,ta,mu
+; LMULMAX1-RV32-NEXT: vle64.v v25, (a0)
+; LMULMAX1-RV32-NEXT: addi a3, a0, 16
+; LMULMAX1-RV32-NEXT: vle64.v v26, (a3)
+; LMULMAX1-RV32-NEXT: vle64.v v27, (a1)
+; LMULMAX1-RV32-NEXT: addi a1, a1, 16
+; LMULMAX1-RV32-NEXT: vle64.v v28, (a1)
+; LMULMAX1-RV32-NEXT: vsetvli a1, a2, e64,m1,ta,mu
+; LMULMAX1-RV32-NEXT: vadd.vv v26, v26, v28
+; LMULMAX1-RV32-NEXT: vadd.vv v25, v25, v27
+; LMULMAX1-RV32-NEXT: vse64.v v25, (a0)
+; LMULMAX1-RV32-NEXT: vse64.v v26, (a3)
+; LMULMAX1-RV32-NEXT: ret
+;
+; LMULMAX1-RV64-LABEL: extract_v4i64:
+; LMULMAX1-RV64: # %bb.0:
+; LMULMAX1-RV64-NEXT: addi a2, zero, 2
+; LMULMAX1-RV64-NEXT: vsetvli a3, a2, e64,m1,ta,mu
+; LMULMAX1-RV64-NEXT: vle64.v v25, (a0)
+; LMULMAX1-RV64-NEXT: addi a3, a0, 16
+; LMULMAX1-RV64-NEXT: vle64.v v26, (a3)
+; LMULMAX1-RV64-NEXT: vle64.v v27, (a1)
+; LMULMAX1-RV64-NEXT: addi a1, a1, 16
+; LMULMAX1-RV64-NEXT: vle64.v v28, (a1)
+; LMULMAX1-RV64-NEXT: vsetvli a1, a2, e64,m1,ta,mu
+; LMULMAX1-RV64-NEXT: vadd.vv v26, v26, v28
+; LMULMAX1-RV64-NEXT: vadd.vv v25, v25, v27
+; LMULMAX1-RV64-NEXT: vse64.v v25, (a0)
+; LMULMAX1-RV64-NEXT: vse64.v v26, (a3)
+; LMULMAX1-RV64-NEXT: ret
+ %a = load <4 x i64>, <4 x i64>* %x
+ %b = load <4 x i64>, <4 x i64>* %y
+ br label %"compute"
+"compute":
+ %c = add <4 x i64> %a, %b
+ store <4 x i64> %c, <4 x i64>* %x
+ ret void
+}
More information about the llvm-commits
mailing list