[llvm] [RISCV] computeKnownBits - add support for RISCVISD::VECREDUCE_ADD_VL (PR #210493)
Sabona Abdi via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 18 12:21:40 PDT 2026
https://github.com/sabonaoabdi updated https://github.com/llvm/llvm-project/pull/210493
>From 57110991abd93729a8f07a50777904a30f2bf2a9 Mon Sep 17 00:00:00 2001
From: sabonaoabdi <sabonaoabdi at gmail.com>
Date: Sat, 18 Jul 2026 14:20:34 -0500
Subject: [PATCH 1/2] [RISCV] Add baseline test coverage for
RISCVISD::VECREDUCE_ADD_VL known bits
---
.../RISCV/rvv/vecreduce-add-vl-knownbits.ll | 89 +++++++++++++++++++
1 file changed, 89 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/rvv/vecreduce-add-vl-knownbits.ll
diff --git a/llvm/test/CodeGen/RISCV/rvv/vecreduce-add-vl-knownbits.ll b/llvm/test/CodeGen/RISCV/rvv/vecreduce-add-vl-knownbits.ll
new file mode 100644
index 0000000000000..db6b415ac40d0
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/vecreduce-add-vl-knownbits.ll
@@ -0,0 +1,89 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc < %s -mtriple=riscv32 -mattr=+v | FileCheck %s --check-prefixes=CHECK,RV32
+; RUN: llc < %s -mtriple=riscv64 -mattr=+v | FileCheck %s --check-prefixes=CHECK,RV64
+; RUN: llc < %s -mtriple=riscv32 -mattr=+v,+experimental-zvabd | FileCheck %s --check-prefixes=ZVABD,RV32ZVABD
+; RUN: llc < %s -mtriple=riscv64 -mattr=+v,+experimental-zvabd | FileCheck %s --check-prefixes=ZVABD,RV64ZVABD
+
+define signext i32 @vecreduce_add_nxv4i32(<vscale x 4 x i32> %v) {
+; CHECK-LABEL: vecreduce_add_nxv4i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; CHECK-NEXT: vmv.s.x v10, zero
+; CHECK-NEXT: vredsum.vs v8, v8, v10
+; CHECK-NEXT: vmv.x.s a0, v8
+; CHECK-NEXT: ret
+;
+; ZVABD-LABEL: vecreduce_add_nxv4i32:
+; ZVABD: # %bb.0:
+; ZVABD-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; ZVABD-NEXT: vmv.s.x v10, zero
+; ZVABD-NEXT: vredsum.vs v8, v8, v10
+; ZVABD-NEXT: vmv.x.s a0, v8
+; ZVABD-NEXT: ret
+ %r = call i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32> %v)
+ ret i32 %r
+}
+
+define signext i32 @vpreduce_add_v4i32_const_evl(i32 %s, <4 x i32> %v, <4 x i1> %m) {
+; CHECK-LABEL: vpreduce_add_v4i32_const_evl:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vmv.s.x v9, a0
+; CHECK-NEXT: vredsum.vs v8, v8, v9, v0.t
+; CHECK-NEXT: vmv.x.s a0, v8
+; CHECK-NEXT: ret
+;
+; ZVABD-LABEL: vpreduce_add_v4i32_const_evl:
+; ZVABD: # %bb.0:
+; ZVABD-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; ZVABD-NEXT: vmv.s.x v9, a0
+; ZVABD-NEXT: vredsum.vs v8, v8, v9, v0.t
+; ZVABD-NEXT: vmv.x.s a0, v8
+; ZVABD-NEXT: ret
+ %r = call i32 @llvm.vp.reduce.add.v4i32(i32 %s, <4 x i32> %v, <4 x i1> %m, i32 4)
+ ret i32 %r
+}
+
+define signext i32 @vpreduce_add_nxv4i32(i32 %s, <vscale x 4 x i32> %v, <vscale x 4 x i1> %m, i32 %evl) {
+; RV32-LABEL: vpreduce_add_nxv4i32:
+; RV32: # %bb.0:
+; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma
+; RV32-NEXT: vmv.s.x v10, a0
+; RV32-NEXT: vsetvli zero, a1, e32, m2, ta, ma
+; RV32-NEXT: vredsum.vs v10, v8, v10, v0.t
+; RV32-NEXT: vmv.x.s a0, v10
+; RV32-NEXT: ret
+;
+; RV64-LABEL: vpreduce_add_nxv4i32:
+; RV64: # %bb.0:
+; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma
+; RV64-NEXT: vmv.s.x v10, a0
+; RV64-NEXT: slli a1, a1, 32
+; RV64-NEXT: srli a1, a1, 32
+; RV64-NEXT: vsetvli zero, a1, e32, m2, ta, ma
+; RV64-NEXT: vredsum.vs v10, v8, v10, v0.t
+; RV64-NEXT: vmv.x.s a0, v10
+; RV64-NEXT: ret
+;
+; RV32ZVABD-LABEL: vpreduce_add_nxv4i32:
+; RV32ZVABD: # %bb.0:
+; RV32ZVABD-NEXT: vsetivli zero, 1, e32, m1, ta, ma
+; RV32ZVABD-NEXT: vmv.s.x v10, a0
+; RV32ZVABD-NEXT: vsetvli zero, a1, e32, m2, ta, ma
+; RV32ZVABD-NEXT: vredsum.vs v10, v8, v10, v0.t
+; RV32ZVABD-NEXT: vmv.x.s a0, v10
+; RV32ZVABD-NEXT: ret
+;
+; RV64ZVABD-LABEL: vpreduce_add_nxv4i32:
+; RV64ZVABD: # %bb.0:
+; RV64ZVABD-NEXT: vsetivli zero, 1, e32, m1, ta, ma
+; RV64ZVABD-NEXT: vmv.s.x v10, a0
+; RV64ZVABD-NEXT: slli a1, a1, 32
+; RV64ZVABD-NEXT: srli a1, a1, 32
+; RV64ZVABD-NEXT: vsetvli zero, a1, e32, m2, ta, ma
+; RV64ZVABD-NEXT: vredsum.vs v10, v8, v10, v0.t
+; RV64ZVABD-NEXT: vmv.x.s a0, v10
+; RV64ZVABD-NEXT: ret
+ %r = call i32 @llvm.vp.reduce.add.nxv4i32(i32 %s, <vscale x 4 x i32> %v, <vscale x 4 x i1> %m, i32 %evl)
+ ret i32 %r
+}
>From 298b658b81230f880df934adc3ab4098cd113e9b Mon Sep 17 00:00:00 2001
From: sabonaoabdi <sabonaoabdi at gmail.com>
Date: Sat, 18 Jul 2026 14:21:04 -0500
Subject: [PATCH 2/2] [RISCV] Add computeKnownBits support for
RISCVISD::VECREDUCE_ADD_VL
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 22 +++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 96b6f391863c4..806dc7f1d12b0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -24108,6 +24108,28 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
Known.Zero.setBitsFrom(Known2.countMaxActiveBits());
break;
}
+ case RISCVISD::VECREDUCE_ADD_VL: {
+ SDValue Src = Op.getOperand(1);
+ SDValue InitVal = Op.getOperand(2);
+ SDValue VL = Op.getOperand(4);
+ unsigned NumElts;
+
+ if (isa<ConstantSDNode>(VL)) {
+ NumElts = VL->getAsZExtVal();
+ } else {
+ const RISCVSubtarget &SubTarget = DAG.getSubtarget<RISCVSubtarget>();
+ auto [Min, Max] = computeVLMAXBounds(Src.getSimpleValueType(), SubTarget);
+ NumElts = Max;
+ }
+
+ KnownBits KnownAcrossElts =
+ DAG.computeKnownBits(Src, APInt::getAllOnes(1), Depth + 1);
+ KnownBits VecSum = KnownAcrossElts.reduceAdd(NumElts);
+ KnownBits Start = DAG.computeKnownBits(InitVal, Depth + 1);
+
+ Known = KnownBits::add(Start, VecSum);
+ break;
+ }
case RISCVISD::CZERO_EQZ:
case RISCVISD::CZERO_NEZ:
Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
More information about the llvm-commits
mailing list