[llvm] [RISCV] Use `experimental-p` extension for zero-extended narrow unsigned types (PR #213260)
Rajveer Singh Bharadwaj via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 2 05:49:58 PDT 2026
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/213260
>From 5298ce2aeb0b88e93de4442e578ba5f5ddc22a3a Mon Sep 17 00:00:00 2001
From: Rajveer <rajveer.developer at icloud.com>
Date: Fri, 31 Jul 2026 17:41:45 +0530
Subject: [PATCH] [RISCV] Use `experimental-p` extension for zero-extended
narrow unsigned types
Resolves #211361
The bits `31:8` remain zero after packed addition due to `padd.b`
carry-out as per ABI, hence we can generate more optimised code instead
of `zext.b` + `add`.
---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 26 ++++++++++++++++++
...-p-extension-narrow-unsigned-arithmetic.ll | 27 +++++++++++++++++++
2 files changed, 53 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/experimental-p-extension-narrow-unsigned-arithmetic.ll
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index f36f27769a353..921c5e1eff79c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1816,6 +1816,32 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
if (tryShrinkShlLogicImm(Node))
return;
+ if (Subtarget->hasStdExtP()) {
+ if (N0->getOpcode() == ISD::ADD) {
+ SDValue AddN0 = N0->getOperand(0);
+ SDValue AddN1 = N0.getOperand(1);
+
+ EVT ValTyN0 = AddN0.getValueType(), ValTyN1 = AddN1.getValueType();
+ if (AddN0.getOpcode() == ISD::AssertZext &&
+ AddN1.getOpcode() == ISD::AssertZext && ValTyN0 == ValTyN1) {
+
+ if (N1C->getZExtValue() == ((1 << 8) - 1)) {
+ SDNode *PADDB = CurDAG->getMachineNode(RISCV::PADD_B, DL, ValTyN0,
+ AddN0, AddN1);
+ ReplaceNode(Node, PADDB);
+ return;
+ }
+
+ if (N1C->getZExtValue() == ((1 << 16) - 1)) {
+ SDNode *PADDH = CurDAG->getMachineNode(RISCV::PADD_H, DL, ValTyN0,
+ AddN0, AddN1);
+ ReplaceNode(Node, PADDH);
+ return;
+ }
+ }
+ }
+ }
+
break;
}
case ISD::MUL: {
diff --git a/llvm/test/CodeGen/RISCV/experimental-p-extension-narrow-unsigned-arithmetic.ll b/llvm/test/CodeGen/RISCV/experimental-p-extension-narrow-unsigned-arithmetic.ll
new file mode 100644
index 0000000000000..7009587a22164
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/experimental-p-extension-narrow-unsigned-arithmetic.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-p \
+; RUN: -verify-machineinstrs < %s | \
+; RUN: FileCheck --check-prefixes=CHECK,RV32 %s
+
+define zeroext i8 @zexti8_paddb(i8 zeroext %x, i8 zeroext %y) {
+; CHECK-LABEL: zexti8_paddb:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: padd.b a0, a1, a0
+; CHECK-NEXT: ret
+entry:
+ %add = add i8 %y, %x
+ ret i8 %add
+}
+
+define zeroext i16 @zexti16_paddh(i16 zeroext %x, i16 zeroext %y) {
+; CHECK-LABEL: zexti16_paddh:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: padd.h a0, a1, a0
+; CHECK-NEXT: ret
+entry:
+ %add = add i16 %y, %x
+ ret i16 %add
+}
+
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; RV32: {{.*}}
More information about the llvm-commits
mailing list