-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[RISCV] When VLEN is exactly known, prefer VLMAX encoding for vsetvli #75412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV] When VLEN is exactly known, prefer VLMAX encoding for vsetvli #75412
Conversation
If we know the exact VLEN, then we can tell if the AVL for particular operation is equivalent to the vsetvli xN, zero, <vtype> encoding. Using this encoding is better than having to materialize an immediate in a register, but worse than being able to use the vsetivli zero, imm, <type> encoding.
|
@llvm/pr-subscribers-backend-risc-v Author: Philip Reames (preames) ChangesIf we know the exact VLEN, then we can tell if the AVL for particular operation is equivalent to the vsetvli xN, zero, <vtype> encoding. Using this encoding is better than having to materialize an immediate in a register, but worse than being able to use the vsetivli zero, imm, <type> encoding. Full diff: https://github.com/llvm/llvm-project/pull/75412.diff 4 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index a75bbb49bedaa1..91bccc77f93fd0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2580,8 +2580,15 @@ static SDValue getAllOnesMask(MVT VecVT, SDValue VL, const SDLoc &DL,
return DAG.getNode(RISCVISD::VMSET_VL, DL, MaskVT, VL);
}
-static SDValue getVLOp(uint64_t NumElts, const SDLoc &DL, SelectionDAG &DAG,
- const RISCVSubtarget &Subtarget) {
+static SDValue getVLOp(uint64_t NumElts, MVT ContainerVT, const SDLoc &DL,
+ SelectionDAG &DAG, const RISCVSubtarget &Subtarget) {
+ // If we know the exact VLEN, our VL is exactly equal to VLMAX, and
+ // we can't encode the AVL as an immediate, use the VLMAX encoding.
+ const auto [MinVLMAX, MaxVLMAX] =
+ RISCVTargetLowering::computeVLMAXBounds(ContainerVT, Subtarget);
+ if (MinVLMAX == MaxVLMAX && NumElts == MinVLMAX && NumElts > 31)
+ return DAG.getRegister(RISCV::X0, Subtarget.getXLenVT());
+
return DAG.getConstant(NumElts, DL, Subtarget.getXLenVT());
}
@@ -2598,7 +2605,7 @@ static std::pair<SDValue, SDValue>
getDefaultVLOps(uint64_t NumElts, MVT ContainerVT, const SDLoc &DL,
SelectionDAG &DAG, const RISCVSubtarget &Subtarget) {
assert(ContainerVT.isScalableVector() && "Expecting scalable container type");
- SDValue VL = getVLOp(NumElts, DL, DAG, Subtarget);
+ SDValue VL = getVLOp(NumElts, ContainerVT, DL, DAG, Subtarget);
SDValue Mask = getAllOnesMask(ContainerVT, VL, DL, DAG);
return {Mask, VL};
}
@@ -8650,7 +8657,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
MVT VT = Op->getSimpleValueType(0);
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
+ SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
+ Subtarget);
SDValue IntID = DAG.getTargetConstant(VlsegInts[NF - 2], DL, XLenVT);
auto *Load = cast<MemIntrinsicSDNode>(Op);
SmallVector<EVT, 9> ContainerVTs(NF, ContainerVT);
@@ -8785,7 +8793,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
MVT VT = Op->getOperand(2).getSimpleValueType();
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
+ SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
+ Subtarget);
SDValue IntID = DAG.getTargetConstant(VssegInts[NF - 2], DL, XLenVT);
SDValue Ptr = Op->getOperand(NF + 2);
@@ -9244,7 +9253,7 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
// Set the vector length to only the number of elements we care about. Note
// that for slideup this includes the offset.
unsigned EndIndex = OrigIdx + SubVecVT.getVectorNumElements();
- SDValue VL = getVLOp(EndIndex, DL, DAG, Subtarget);
+ SDValue VL = getVLOp(EndIndex, ContainerVT, DL, DAG, Subtarget);
// Use tail agnostic policy if we're inserting over Vec's tail.
unsigned Policy = RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED;
@@ -9421,7 +9430,8 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).first;
// Set the vector length to only the number of elements we care about. This
// avoids sliding down elements we're going to discard straight away.
- SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), DL, DAG, Subtarget);
+ SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), ContainerVT, DL, DAG,
+ Subtarget);
SDValue SlidedownAmt = DAG.getConstant(OrigIdx, DL, XLenVT);
SDValue Slidedown =
getVSlidedown(DAG, Subtarget, DL, ContainerVT,
@@ -9828,7 +9838,7 @@ RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
MVT XLenVT = Subtarget.getXLenVT();
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
+ SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
SDValue IntID = DAG.getTargetConstant(
@@ -9872,7 +9882,8 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
+ SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
+ Subtarget);
SDValue NewValue =
convertToScalableVector(ContainerVT, StoreVal, DAG, Subtarget);
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
index b4260b04604cd0..0b9db09aab3a9c 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll
@@ -284,14 +284,22 @@ define void @extract_v8i32_nxv16i32_8(<vscale x 16 x i32> %x, ptr %y) {
}
define void @extract_v8i1_v64i1_0(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v8i1_v64i1_0:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; CHECK-V-LABEL: extract_v8i1_v64i1_0:
+; CHECK-V: # %bb.0:
+; CHECK-V-NEXT: li a2, 64
+; CHECK-V-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-V-NEXT: vlm.v v8, (a0)
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vsm.v v8, (a1)
+; CHECK-V-NEXT: ret
+;
+; CHECK-KNOWNVLEN128-LABEL: extract_v8i1_v64i1_0:
+; CHECK-KNOWNVLEN128: # %bb.0:
+; CHECK-KNOWNVLEN128-NEXT: vsetvli a2, zero, e8, m4, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vlm.v v8, (a0)
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a1)
+; CHECK-KNOWNVLEN128-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <8 x i1> @llvm.vector.extract.v8i1.v64i1(<64 x i1> %a, i64 0)
store <8 x i1> %c, ptr %y
@@ -299,16 +307,26 @@ define void @extract_v8i1_v64i1_0(ptr %x, ptr %y) {
}
define void @extract_v8i1_v64i1_8(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v8i1_v64i1_8:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 1
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; CHECK-V-LABEL: extract_v8i1_v64i1_8:
+; CHECK-V: # %bb.0:
+; CHECK-V-NEXT: li a2, 64
+; CHECK-V-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-V-NEXT: vlm.v v8, (a0)
+; CHECK-V-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
+; CHECK-V-NEXT: vslidedown.vi v8, v8, 1
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vsm.v v8, (a1)
+; CHECK-V-NEXT: ret
+;
+; CHECK-KNOWNVLEN128-LABEL: extract_v8i1_v64i1_8:
+; CHECK-KNOWNVLEN128: # %bb.0:
+; CHECK-KNOWNVLEN128-NEXT: vsetvli a2, zero, e8, m4, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vlm.v v8, (a0)
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 1
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a1)
+; CHECK-KNOWNVLEN128-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <8 x i1> @llvm.vector.extract.v8i1.v64i1(<64 x i1> %a, i64 8)
store <8 x i1> %c, ptr %y
@@ -316,16 +334,26 @@ define void @extract_v8i1_v64i1_8(ptr %x, ptr %y) {
}
define void @extract_v8i1_v64i1_48(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v8i1_v64i1_48:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 6
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; CHECK-V-LABEL: extract_v8i1_v64i1_48:
+; CHECK-V: # %bb.0:
+; CHECK-V-NEXT: li a2, 64
+; CHECK-V-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-V-NEXT: vlm.v v8, (a0)
+; CHECK-V-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
+; CHECK-V-NEXT: vslidedown.vi v8, v8, 6
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vsm.v v8, (a1)
+; CHECK-V-NEXT: ret
+;
+; CHECK-KNOWNVLEN128-LABEL: extract_v8i1_v64i1_48:
+; CHECK-KNOWNVLEN128: # %bb.0:
+; CHECK-KNOWNVLEN128-NEXT: vsetvli a2, zero, e8, m4, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vlm.v v8, (a0)
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 1, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 6
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a1)
+; CHECK-KNOWNVLEN128-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <8 x i1> @llvm.vector.extract.v8i1.v64i1(<64 x i1> %a, i64 48)
store <8 x i1> %c, ptr %y
@@ -407,22 +435,38 @@ define void @extract_v8i1_nxv64i1_192(<vscale x 64 x i1> %x, ptr %y) {
}
define void @extract_v2i1_v64i1_0(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_v64i1_0:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v0, (a0)
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; CHECK-V-LABEL: extract_v2i1_v64i1_0:
+; CHECK-V: # %bb.0:
+; CHECK-V-NEXT: li a2, 64
+; CHECK-V-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-V-NEXT: vlm.v v0, (a0)
+; CHECK-V-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-V-NEXT: vmv.v.i v8, 0
+; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vmv.v.i v9, 0
+; CHECK-V-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-V-NEXT: vmv.v.v v9, v8
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vmsne.vi v8, v9, 0
+; CHECK-V-NEXT: vsm.v v8, (a1)
+; CHECK-V-NEXT: ret
+;
+; CHECK-KNOWNVLEN128-LABEL: extract_v2i1_v64i1_0:
+; CHECK-KNOWNVLEN128: # %bb.0:
+; CHECK-KNOWNVLEN128-NEXT: vsetvli a2, zero, e8, m4, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vlm.v v0, (a0)
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0
+; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v9, 0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.v v9, v8
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v8, v9, 0
+; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a1)
+; CHECK-KNOWNVLEN128-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 0)
store <2 x i1> %c, ptr %y
@@ -430,27 +474,48 @@ define void @extract_v2i1_v64i1_0(ptr %x, ptr %y) {
}
define void @extract_v2i1_v64i1_2(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_v64i1_2:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v0, (a0)
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma
-; CHECK-NEXT: vslidedown.vi v8, v8, 2
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; CHECK-V-LABEL: extract_v2i1_v64i1_2:
+; CHECK-V: # %bb.0:
+; CHECK-V-NEXT: li a2, 64
+; CHECK-V-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-V-NEXT: vlm.v v0, (a0)
+; CHECK-V-NEXT: vmv.v.i v8, 0
+; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-V-NEXT: vsetivli zero, 2, e8, m1, ta, ma
+; CHECK-V-NEXT: vslidedown.vi v8, v8, 2
+; CHECK-V-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-V-NEXT: vmsne.vi v0, v8, 0
+; CHECK-V-NEXT: vmv.v.i v8, 0
+; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vmv.v.i v9, 0
+; CHECK-V-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-V-NEXT: vmv.v.v v9, v8
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vmsne.vi v8, v9, 0
+; CHECK-V-NEXT: vsm.v v8, (a1)
+; CHECK-V-NEXT: ret
+;
+; CHECK-KNOWNVLEN128-LABEL: extract_v2i1_v64i1_2:
+; CHECK-KNOWNVLEN128: # %bb.0:
+; CHECK-KNOWNVLEN128-NEXT: vsetvli a2, zero, e8, m4, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vlm.v v0, (a0)
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0
+; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, m1, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 2
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v0, v8, 0
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0
+; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v9, 0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.v v9, v8
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v8, v9, 0
+; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a1)
+; CHECK-KNOWNVLEN128-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 2)
store <2 x i1> %c, ptr %y
@@ -458,28 +523,50 @@ define void @extract_v2i1_v64i1_2(ptr %x, ptr %y) {
}
define void @extract_v2i1_v64i1_42(ptr %x, ptr %y) {
-; CHECK-LABEL: extract_v2i1_v64i1_42:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a2, 64
-; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, ma
-; CHECK-NEXT: vlm.v v0, (a0)
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: li a0, 42
-; CHECK-NEXT: vsetivli zero, 2, e8, m4, ta, ma
-; CHECK-NEXT: vslidedown.vx v8, v8, a0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmv.v.i v9, 0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
-; CHECK-NEXT: vmv.v.v v9, v8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: vsm.v v8, (a1)
-; CHECK-NEXT: ret
+; CHECK-V-LABEL: extract_v2i1_v64i1_42:
+; CHECK-V: # %bb.0:
+; CHECK-V-NEXT: li a2, 64
+; CHECK-V-NEXT: vsetvli zero, a2, e8, m4, ta, ma
+; CHECK-V-NEXT: vlm.v v0, (a0)
+; CHECK-V-NEXT: vmv.v.i v8, 0
+; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-V-NEXT: li a0, 42
+; CHECK-V-NEXT: vsetivli zero, 2, e8, m4, ta, ma
+; CHECK-V-NEXT: vslidedown.vx v8, v8, a0
+; CHECK-V-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-V-NEXT: vmsne.vi v0, v8, 0
+; CHECK-V-NEXT: vmv.v.i v8, 0
+; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vmv.v.i v9, 0
+; CHECK-V-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-V-NEXT: vmv.v.v v9, v8
+; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-V-NEXT: vmsne.vi v8, v9, 0
+; CHECK-V-NEXT: vsm.v v8, (a1)
+; CHECK-V-NEXT: ret
+;
+; CHECK-KNOWNVLEN128-LABEL: extract_v2i1_v64i1_42:
+; CHECK-KNOWNVLEN128: # %bb.0:
+; CHECK-KNOWNVLEN128-NEXT: vsetvli a2, zero, e8, m4, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vlm.v v0, (a0)
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0
+; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-KNOWNVLEN128-NEXT: li a0, 42
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, m4, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vslidedown.vx v8, v8, a0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf8, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v0, v8, 0
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0
+; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v9, 0
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf2, tu, ma
+; CHECK-KNOWNVLEN128-NEXT: vmv.v.v v9, v8
+; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v8, v9, 0
+; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a1)
+; CHECK-KNOWNVLEN128-NEXT: ret
%a = load <64 x i1>, ptr %x
%c = call <2 x i1> @llvm.vector.extract.v2i1.v64i1(<64 x i1> %a, i64 42)
store <2 x i1> %c, ptr %y
@@ -660,6 +747,3 @@ declare <2 x i8> @llvm.vector.extract.v2i8.nxv2i8(<vscale x 2 x i8> %vec, i64 %i
declare <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %vec, i64 %idx)
declare <8 x i32> @llvm.vector.extract.v8i32.nxv16i32(<vscale x 16 x i32> %vec, i64 %idx)
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-KNOWNVLEN128: {{.*}}
-; CHECK-V: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-load.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-load.ll
index ed27c9c7eb3445..bcf2b0655b1763 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-load.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-load.ll
@@ -160,8 +160,7 @@ define <16 x i8> @exact_vlen_i8_m1(ptr %p) vscale_range(2,2) {
define <32 x i8> @exact_vlen_i8_m2(ptr %p) vscale_range(2,2) {
; CHECK-LABEL: exact_vlen_i8_m2:
; CHECK: # %bb.0:
-; CHECK-NEXT: li a1, 32
-; CHECK-NEXT: vsetvli zero, a1, e8, m2, ta, ma
+; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma
; CHECK-NEXT: vle8.v v8, (a0)
; CHECK-NEXT: ret
%v = load <32 x i8>, ptr %p
@@ -171,8 +170,7 @@ define <32 x i8> @exact_vlen_i8_m2(ptr %p) vscale_range(2,2) {
define <128 x i8> @exact_vlen_i8_m8(ptr %p) vscale_range(2,2) {
; CHECK-LABEL: exact_vlen_i8_m8:
; CHECK: # %bb.0:
-; CHECK-NEXT: li a1, 128
-; CHECK-NEXT: vsetvli zero, a1, e8, m8, ta, ma
+; CHECK-NEXT: vsetvli a1, zero, e8, m8, ta, ma
; CHECK-NEXT: vle8.v v8, (a0)
; CHECK-NEXT: ret
%v = load <128 x i8>, ptr %p
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-store.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-store.ll
index 7c6c70221d851a..8e3ef615428f35 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-store.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-store.ll
@@ -264,8 +264,7 @@ define void @exact_vlen_i8_m1(ptr %p) vscale_range(2,2) {
define void @exact_vlen_i8_m2(ptr %p) vscale_range(2,2) {
; CHECK-LABEL: exact_vlen_i8_m2:
; CHECK: # %bb.0:
-; CHECK-NEXT: li a1, 32
-; CHECK-NEXT: vsetvli zero, a1, e8, m2, ta, ma
+; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma
; CHECK-NEXT: vmv.v.i v8, 0
; CHECK-NEXT: vse8.v v8, (a0)
; CHECK-NEXT: ret
@@ -276,8 +275,7 @@ define void @exact_vlen_i8_m2(ptr %p) vscale_range(2,2) {
define void @exact_vlen_i8_m8(ptr %p) vscale_range(2,2) {
; CHECK-LABEL: exact_vlen_i8_m8:
; CHECK: # %bb.0:
-; CHECK-NEXT: li a1, 128
-; CHECK-NEXT: vsetvli zero, a1, e8, m8, ta, ma
+; CHECK-NEXT: vsetvli a1, zero, e8, m8, ta, ma
; CHECK-NEXT: vmv.v.i v8, 0
; CHECK-NEXT: vse8.v v8, (a0)
; CHECK-NEXT: ret
|
You can test this locally with the following command:git-clang-format --diff 12af9c833797b579cde97b2378cb3a3153edbed4 d69ef3d7d2b4b94388f75eaa550e79f323c2a8f6 -- llvm/lib/Target/RISCV/RISCVISelLowering.cppView the diff from clang-format here.diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 91bccc77f9..a5c63705ba 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8657,8 +8657,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
MVT VT = Op->getSimpleValueType(0);
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
- Subtarget);
+ SDValue VL =
+ getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
SDValue IntID = DAG.getTargetConstant(VlsegInts[NF - 2], DL, XLenVT);
auto *Load = cast<MemIntrinsicSDNode>(Op);
SmallVector<EVT, 9> ContainerVTs(NF, ContainerVT);
@@ -8793,8 +8793,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
MVT VT = Op->getOperand(2).getSimpleValueType();
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
- Subtarget);
+ SDValue VL =
+ getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
SDValue IntID = DAG.getTargetConstant(VssegInts[NF - 2], DL, XLenVT);
SDValue Ptr = Op->getOperand(NF + 2);
@@ -9838,7 +9838,8 @@ RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
MVT XLenVT = Subtarget.getXLenVT();
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
+ SDValue VL =
+ getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
SDValue IntID = DAG.getTargetConstant(
@@ -9882,8 +9883,8 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
MVT ContainerVT = getContainerForFixedLengthVector(VT);
- SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
- Subtarget);
+ SDValue VL =
+ getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
SDValue NewValue =
convertToScalableVector(ContainerVT, StoreVal, DAG, Subtarget);
|
topperc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
In llvm#75412 and llvm#75509 we started to use the vsetvli a0, zero encoding to reduce register pressure when we know the exact VLEN. We do this by canonicalizing VL ops to X0 in RISCVISelLowering. This is only needed for cases where the AVL doesn't fit inside an immediate though, since we already have code in RISCVInsertVSETVLI that detects if we know the exact VLEN and uses the immediate encoding if possible. This patch removes the need to do the canonicalization in RISCVISelLowering by handling said case in RISCVInsertVSETVLI itself. There are a handful of reasons I'm proposing to do this: - It keeps the vsetvli logic in the one pass - We get to move code out of SelectionDAG so we don't forget about it in GlobalISEL when the time comes - Canonicalizing the VL in RISCVISelLowering means that we lose the original VL for fixed length vectors, which might be useful information for passes that sit between lowering and RISCVInsertVSETVLI. (I discovered this when working on a patch for RISCVFoldMasks.cpp that worked on fixed length vectors)
In llvm#75412 and llvm#75509 we started to use the vsetvli a0, zero encoding to reduce register pressure when we know the exact VLEN. We do this by canonicalizing VL ops to X0 in RISCVISelLowering. This is only needed for cases where the AVL doesn't fit inside an immediate though, since we already have code in RISCVInsertVSETVLI that detects if we know the exact VLEN and uses the immediate encoding if possible. This patch removes the need to do the canonicalization in RISCVISelLowering by handling said case in RISCVInsertVSETVLI itself. There are a handful of reasons I'm proposing to do this: - It keeps the vsetvli logic in the one pass - We get to move code out of SelectionDAG so we don't forget about it in GlobalISEL when the time comes - Canonicalizing the VL in RISCVISelLowering means that we lose the original VL for fixed length vectors, which might be useful information for passes that sit between lowering and RISCVInsertVSETVLI. (I discovered this when working on a patch for RISCVFoldMasks.cpp that worked on fixed length vectors)
In llvm#75412 and llvm#75509 we started to use the vsetvli a0, zero encoding to reduce register pressure when we know the exact VLEN. We do this by canonicalizing VL ops to X0 in RISCVISelLowering. This is only needed for cases where the AVL doesn't fit inside an immediate though, since we already have code in RISCVInsertVSETVLI that detects if we know the exact VLEN and uses the immediate encoding if possible. This patch removes the need to do the canonicalization in RISCVISelLowering by handling said case in RISCVInsertVSETVLI itself. There are a handful of reasons I'm proposing to do this: - It keeps the vsetvli logic in the one pass - We get to move code out of SelectionDAG so we don't forget about it in GlobalISEL when the time comes - Canonicalizing the VL in RISCVISelLowering means that we lose the original VL for fixed length vectors, which might be useful information for passes that sit between lowering and RISCVInsertVSETVLI. (I discovered this when working on a patch for RISCVFoldMasks.cpp that worked on fixed length vectors)
If we know the exact VLEN, then we can tell if the AVL for particular operation is equivalent to the vsetvli xN, zero, encoding. Using this encoding is better than having to materialize an immediate in a register, but worse than being able to use the vsetivli zero, imm, encoding.