-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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] Optimize undef Even vector in getWideningInterleave. #88221
Conversation
We recently optimized the code when the Odd vector was undef to fix a poison bug. There are additional optimizations we can do if the even vector is undef. With Zvbb, we can use a single vwsll. Without Zvbb, we can use a vzext.vf2 and a vsll.
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesWe recently optimized the code when the Odd vector was undef to fix a poison bug. There are additional optimizations we can do if the even vector is undef. With Zvbb, we can use a single vwsll. Without Zvbb, we can use a vzext.vf2 and a vsll. Full diff: https://github.com/llvm/llvm-project/pull/88221.diff 2 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 80cc41b458ca81..cae2d792ac5590 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4638,8 +4638,19 @@ static SDValue getWideningInterleave(SDValue EvenV, SDValue OddV,
Subtarget.getXLenVT()));
Interleaved = DAG.getNode(RISCVISD::VWSLL_VL, DL, WideContainerVT, OddV,
OffsetVec, Passthru, Mask, VL);
- Interleaved = DAG.getNode(RISCVISD::VWADDU_W_VL, DL, WideContainerVT,
- Interleaved, EvenV, Passthru, Mask, VL);
+ if (!EvenV.isUndef())
+ Interleaved = DAG.getNode(RISCVISD::VWADDU_W_VL, DL, WideContainerVT,
+ Interleaved, EvenV, Passthru, Mask, VL);
+ } else if (EvenV.isUndef()) {
+ Interleaved =
+ DAG.getNode(RISCVISD::VZEXT_VL, DL, WideContainerVT, OddV, Mask, VL);
+
+ SDValue OffsetVec =
+ DAG.getSplatVector(WideContainerVT, DL,
+ DAG.getConstant(VecVT.getScalarSizeInBits(), DL,
+ Subtarget.getXLenVT()));
+ Interleaved = DAG.getNode(RISCVISD::SHL_VL, DL, WideContainerVT,
+ Interleaved, OffsetVec, Passthru, Mask, VL);
} else {
// FIXME: We should freeze the odd vector here. We already handled the case
// of provably undef/poison above.
diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-interleave.ll b/llvm/test/CodeGen/RISCV/rvv/vector-interleave.ll
index 0992c9fe495f43..4b6ad0f27214d0 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vector-interleave.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vector-interleave.ll
@@ -674,6 +674,26 @@ define <vscale x 8 x i32> @vector_interleave_nxv8i32_nxv4i32_poison(<vscale x 4
ret <vscale x 8 x i32> %res
}
+define <vscale x 8 x i32> @vector_interleave_nxv8i32_nxv4i32_poison2(<vscale x 4 x i32> %a) {
+; CHECK-LABEL: vector_interleave_nxv8i32_nxv4i32_poison2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e64, m4, ta, ma
+; CHECK-NEXT: vzext.vf2 v12, v8
+; CHECK-NEXT: li a0, 32
+; CHECK-NEXT: vsll.vx v8, v12, a0
+; CHECK-NEXT: ret
+;
+; ZVBB-LABEL: vector_interleave_nxv8i32_nxv4i32_poison2:
+; ZVBB: # %bb.0:
+; ZVBB-NEXT: li a0, 32
+; ZVBB-NEXT: vsetvli a1, zero, e32, m2, ta, ma
+; ZVBB-NEXT: vwsll.vx v12, v8, a0
+; ZVBB-NEXT: vmv4r.v v8, v12
+; ZVBB-NEXT: ret
+ %res = call <vscale x 8 x i32> @llvm.experimental.vector.interleave2.nxv8i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a)
+ ret <vscale x 8 x i32> %res
+}
+
declare <vscale x 64 x half> @llvm.experimental.vector.interleave2.nxv64f16(<vscale x 32 x half>, <vscale x 32 x half>)
declare <vscale x 32 x float> @llvm.experimental.vector.interleave2.nxv32f32(<vscale x 16 x float>, <vscale x 16 x float>)
declare <vscale x 16 x double> @llvm.experimental.vector.interleave2.nxv16f64(<vscale x 8 x double>, <vscale x 8 x double>)
|
SDValue OffsetVec = | ||
DAG.getSplatVector(WideContainerVT, DL, | ||
DAG.getConstant(VecVT.getScalarSizeInBits(), DL, | ||
Subtarget.getXLenVT())); |
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.
Does this work?
SDValue OffsetVec = | |
DAG.getSplatVector(WideContainerVT, DL, | |
DAG.getConstant(VecVT.getScalarSizeInBits(), DL, | |
Subtarget.getXLenVT())); | |
SDValue OffsetVec = DAG.getConstant(VecVT.getScalarSizeInBits(), DL, WideContainerVT); |
We recently optimized the code when the Odd vector was undef to fix a poison bug.
There are additional optimizations we can do if the even vector is undef. With Zvbb, we can use a single vwsll. Without Zvbb, we can use a vzext.vf2 and a vsll.