[llvm] [RISCV] Implement codegen for XAndesPerf lea instructions (PR #137925)
Jim Lin via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 29 22:38:43 PDT 2025
https://github.com/tclin914 created https://github.com/llvm/llvm-project/pull/137925
This patch add the patterns for generating XAndesPerf lea instructions.
The operation of LEA family instructions is:
rd = rs1 + rs2 * (the number of bytes)
The variants with *.ze suffix are RV64 only and its operation is:
rd = rs1 + ZE32(rs2[31:0]) * (the number of bytes)
>From 253317e0c265ec77929ecedf503bbc1cf183205b Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Thu, 17 Apr 2025 16:55:00 +0800
Subject: [PATCH] [RISCV] Implement codegen for XAndesPerf lea instructions
This patch add the patterns for generating XAndesPerf lea instructions.
The operation of LEA family instructions is:
rd = rs1 + rs2 * (the number of bytes)
The variants with *.ze suffix are RV64 only and its operation is:
rd = rs1 + ZE32(rs2[31:0]) * (the number of bytes)
---
llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td | 25 ++++++++++
llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 33 +++++++++++++
llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 46 +++++++++++++++++++
3 files changed, 104 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/rv32xandesperf.ll
create mode 100644 llvm/test/CodeGen/RISCV/rv64xandesperf.ll
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index 2ec768435259c..e59a7c9353b8a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -356,3 +356,28 @@ def NDS_LDGP : NDSRVInstLDGP<0b011, "nds.ldgp">;
def NDS_SDGP : NDSRVInstSDGP<0b111, "nds.sdgp">;
} // Predicates = [HasVendorXAndesPerf, IsRV64]
} // DecoderNamespace = "XAndes"
+
+// Patterns
+
+let Predicates = [HasVendorXAndesPerf] in {
+class NDS_LEAPat<int shamt, RVInstR Inst>
+ : Pat<(add (XLenVT GPR:$rs1), (shl GPR:$rs2, (XLenVT shamt))),
+ (Inst GPR:$rs1, GPR:$rs2)>;
+
+def : NDS_LEAPat<1, NDS_LEA_H>;
+def : NDS_LEAPat<2, NDS_LEA_W>;
+def : NDS_LEAPat<3, NDS_LEA_D>;
+} // Predicates = [HasVendorXAndesPerf]
+
+let Predicates = [HasVendorXAndesPerf, IsRV64] in {
+def : Pat<(add (XLenVT GPR:$rs1), (zexti32 (i64 GPR:$rs2))),
+ (NDS_LEA_B_ZE GPR:$rs1, GPR:$rs2)>;
+
+class NDS_LEA_ZEPat<int shamt, RVInstR Inst>
+ : Pat<(add GPR:$rs1, (shl (zexti32 (XLenVT GPR:$rs2)), (XLenVT shamt))),
+ (Inst GPR:$rs1, GPR:$rs2)>;
+
+def : NDS_LEA_ZEPat<1, NDS_LEA_H_ZE>;
+def : NDS_LEA_ZEPat<2, NDS_LEA_W_ZE>;
+def : NDS_LEA_ZEPat<3, NDS_LEA_D_ZE>;
+} // Predicates = [HasVendorXAndesPerf, IsRV64]
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
new file mode 100644
index 0000000000000..e99c9ee5af587
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -0,0 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O0 -mtriple=riscv32 -mattr=+xandesperf -verify-machineinstrs < %s \
+; RUN: | FileCheck %s
+
+define i32 @lea_h(i32 %a, i32 %b) {
+; CHECK-LABEL: lea_h:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.lea.h a0, a0, a1
+; CHECK-NEXT: ret
+ %shl = shl i32 %b, 1
+ %ret = add i32 %a, %shl
+ ret i32 %ret
+}
+
+define i32 @lea_w(i32 %a, i32 %b) {
+; CHECK-LABEL: lea_w:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.lea.w a0, a0, a1
+; CHECK-NEXT: ret
+ %shl = shl i32 %b, 2
+ %ret = add i32 %a, %shl
+ ret i32 %ret
+}
+
+define i32 @lea_d(i32 %a, i32 %b) {
+; CHECK-LABEL: lea_d:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.lea.d a0, a0, a1
+; CHECK-NEXT: ret
+ %shl = shl i32 %b, 3
+ %ret = add i32 %a, %shl
+ ret i32 %ret
+}
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
new file mode 100644
index 0000000000000..6349272847a4a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv64 -mattr=+xandesperf -verify-machineinstrs < %s \
+; RUN: | FileCheck %s
+
+define i64 @lea_b_ze(i32 %a, i64 %b) {
+; CHECK-LABEL: lea_b_ze:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.lea.b.ze a0, a1, a0
+; CHECK-NEXT: ret
+ %conv = zext i32 %a to i64
+ %add = add i64 %conv, %b
+ ret i64 %add
+}
+
+define i64 @lea_h_ze(i32 %a, i64 %b) {
+; CHECK-LABEL: lea_h_ze:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.lea.h.ze a0, a1, a0
+; CHECK-NEXT: ret
+ %conv = zext i32 %a to i64
+ %shl = shl nuw nsw i64 %conv, 1
+ %add = add i64 %shl, %b
+ ret i64 %add
+}
+
+define i64 @lea_w_ze(i32 %a, i64 %b) {
+; CHECK-LABEL: lea_w_ze:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.lea.w.ze a0, a1, a0
+; CHECK-NEXT: ret
+ %conv = zext i32 %a to i64
+ %shl = shl nuw nsw i64 %conv, 2
+ %add = add i64 %shl, %b
+ ret i64 %add
+}
+
+define i64 @lea_d_ze(i32 %a, i64 %b) {
+; CHECK-LABEL: lea_d_ze:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.lea.d.ze a0, a1, a0
+; CHECK-NEXT: ret
+ %conv = zext i32 %a to i64
+ %shl = shl nuw nsw i64 %conv, 3
+ %add = add i64 %shl, %b
+ ret i64 %add
+}
More information about the llvm-commits
mailing list