[llvm] 298b7a4 - [RISCV] Don't use VL node when lowering scalable mask reductions (#223392)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 14 09:48:03 PDT 2026
Author: Luke Lau
Date: 2026-09-15T00:47:58+08:00
New Revision: 298b7a4b8c5a61302634bd657e1d1e471a257f4c
URL: https://github.com/llvm/llvm-project/commit/298b7a4b8c5a61302634bd657e1d1e471a257f4c
DIFF: https://github.com/llvm/llvm-project/commit/298b7a4b8c5a61302634bd657e1d1e471a257f4c.diff
LOG: [RISCV] Don't use VL node when lowering scalable mask reductions (#223392)
Using ISD::XOR gives us the generic not (setcc cc) -> setcc inverse-cc
combine. With the VL optimizer we still get the same VL propagated.
Restricted to just scalable vectors since some fixed vector patterns
break without the VL node.
The VP test doesn't improve because
1) VP reductions get legalized during regular op legalization, not
vector legalization
2) so generic DAGCombines don't get a chance to run before the
(splat_vector 1) is legalized to vmset_vl.
We can fix this by keeping the (splat_vector 1) legal, but this is left
to another PR.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/rvv/vreductions-mask-vp.ll
llvm/test/CodeGen/RISCV/rvv/vreductions-mask.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b040f17f085b0..6109d4d4bfe47 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -13798,11 +13798,11 @@ SDValue RISCVTargetLowering::lowerVectorMaskVecReduction(SDValue Op,
case ISD::VECREDUCE_AND:
case ISD::VP_REDUCE_AND: {
// vcpop ~x == 0
- SDValue TrueMask = DAG.getNode(RISCVISD::VMSET_VL, DL, ContainerVT, VL);
- if (IsVP || VecVT.isFixedLengthVector())
- Vec = DAG.getNode(RISCVISD::VMXOR_VL, DL, ContainerVT, Vec, TrueMask, VL);
+ if (VecVT.isFixedLengthVector())
+ Vec = DAG.getNode(RISCVISD::VMXOR_VL, DL, ContainerVT, Vec,
+ DAG.getAllOnesConstant(DL, ContainerVT), VL);
else
- Vec = DAG.getNode(ISD::XOR, DL, ContainerVT, Vec, TrueMask);
+ Vec = DAG.getNOT(DL, Vec, ContainerVT);
Vec = DAG.getNode(RISCVISD::VCPOP_VL, DL, XLenVT, Vec, Mask, VL);
CC = ISD::SETEQ;
break;
diff --git a/llvm/test/CodeGen/RISCV/rvv/vreductions-mask-vp.ll b/llvm/test/CodeGen/RISCV/rvv/vreductions-mask-vp.ll
index 2576fa1358457..ef2b42cf8458b 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vreductions-mask-vp.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vreductions-mask-vp.ll
@@ -955,3 +955,18 @@ define zeroext i1 @vpreduce_mul_nxv64i1(i1 zeroext %s, <vscale x 64 x i1> %v, <v
%r = call i1 @llvm.vp.reduce.mul.nxv64i1(i1 %s, <vscale x 64 x i1> %v, <vscale x 64 x i1> %m, i32 %evl)
ret i1 %r
}
+
+define zeroext i1 @vpreduce_and_icmp(i1 zeroext %s, <vscale x 8 x i8> %v, <vscale x 8 x i1> %m, i32 zeroext %evl) {
+; CHECK-LABEL: vpreduce_and_icmp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli zero, a1, e8, m1, ta, ma
+; CHECK-NEXT: vmsle.vi v8, v8, 4
+; CHECK-NEXT: vmnot.m v8, v8
+; CHECK-NEXT: vcpop.m a1, v8, v0.t
+; CHECK-NEXT: seqz a1, a1
+; CHECK-NEXT: and a0, a1, a0
+; CHECK-NEXT: ret
+ %c = icmp slt <vscale x 8 x i8> %v, splat (i8 5)
+ %red = call i1 @llvm.vp.reduce.and(i1 %s, <vscale x 8 x i1> %c, <vscale x 8 x i1> %m, i32 zeroext %evl)
+ ret i1 %red
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vreductions-mask.ll b/llvm/test/CodeGen/RISCV/rvv/vreductions-mask.ll
index d41eff0d64fb3..5703f89a1b0ed 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vreductions-mask.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vreductions-mask.ll
@@ -1128,3 +1128,16 @@ define zeroext i1 @vreduce_smin_nxv1024i1(<vscale x 1024 x i1> %v) {
%red = call i1 @llvm.vector.reduce.smin.nxv1024i1(<vscale x 1024 x i1> %v)
ret i1 %red
}
+
+define i1 @vreduce_and_icmp(<vscale x 8 x i8> %v) {
+; CHECK-LABEL: vreduce_and_icmp:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
+; CHECK-NEXT: vmsgt.vi v8, v8, 4
+; CHECK-NEXT: vcpop.m a0, v8
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %c = icmp slt <vscale x 8 x i8> %v, splat (i8 5)
+ %red = call i1 @llvm.vector.reduce.and(<vscale x 8 x i1> %c)
+ ret i1 %red
+}
More information about the llvm-commits
mailing list