[llvm] [RISCV] Add sext_inreg patterns for XAndesPerf nds.bfos instruction (PR #139714)
Jim Lin via llvm-commits
llvm-commits at lists.llvm.org
Tue May 13 18:33:34 PDT 2025
https://github.com/tclin914 updated https://github.com/llvm/llvm-project/pull/139714
>From 850023cf9ec1b18c483c21dab38c27af745d9344 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Fri, 18 Apr 2025 13:18:17 +0800
Subject: [PATCH 1/2] [RISCV] Add sext_inreg patterns for XAndesPerf nds.bfos
instruction
Add the patterns sign_extend_inreg i1/i8/i16/i32.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 5 +-
llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td | 5 +
llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 152 ++++++++++++++++++
llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 135 ++++++++++++++++
llvm/test/CodeGen/RISCV/rv64zba.ll | 8 +-
5 files changed, 299 insertions(+), 6 deletions(-)
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/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 0f93bd9fef060..597b3adacc8bc 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -309,13 +309,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::VASTART, MVT::Other, Custom);
setOperationAction({ISD::VAARG, ISD::VACOPY, ISD::VAEND}, MVT::Other, Expand);
- if (!Subtarget.hasVendorXTHeadBb())
+ if (!Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXAndesPerf())
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
setOperationAction(ISD::EH_DWARF_CFA, MVT::i32, Custom);
if (!Subtarget.hasStdExtZbb() && !Subtarget.hasVendorXTHeadBb() &&
- !(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()))
+ !(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()) &&
+ !Subtarget.hasVendorXAndesPerf())
setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16}, Expand);
if (Subtarget.is64Bit()) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index aa70a9d03cc1f..97b25530db242 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -404,6 +404,11 @@ def NDS_VFPMADB_VF : NDSRVInstVFPMAD<0b000011, "nds.vfpmadb">;
let Predicates = [HasVendorXAndesPerf] in {
+def : Pat<(sext_inreg (XLenVT GPR:$rs1), i32), (NDS_BFOS GPR:$rs1, 31, 0)>;
+def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (NDS_BFOS GPR:$rs1, 15, 0)>;
+def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (NDS_BFOS GPR:$rs1, 7, 0)>;
+def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (NDS_BFOS GPR:$rs1, 0, 0)>;
+
defm : ShxAddPat<1, NDS_LEA_H>;
defm : ShxAddPat<2, NDS_LEA_W>;
defm : ShxAddPat<3, NDS_LEA_D>;
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
new file mode 100644
index 0000000000000..efe5b4a306fee
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -0,0 +1,152 @@
+; 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 @sexti1_i32(i32 %a) {
+; CHECK-LABEL: sexti1_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %shl = shl i32 %a, 31
+ %shr = ashr exact i32 %shl, 31
+ ret i32 %shr
+}
+
+define i32 @sexti1_i32_2(i1 %a) {
+; CHECK-LABEL: sexti1_i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %1 = sext i1 %a to i32
+ ret i32 %1
+}
+
+define i32 @sexti8_i32(i32 %a) {
+; CHECK-LABEL: sexti8_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: ret
+ %shl = shl i32 %a, 24
+ %shr = ashr exact i32 %shl, 24
+ ret i32 %shr
+}
+
+define i32 @sexti8_i32_2(i8 %a) {
+; CHECK-LABEL: sexti8_i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: ret
+ %1 = sext i8 %a to i32
+ ret i32 %1
+}
+
+define i32 @sexti16_i32(i32 %a) {
+; CHECK-LABEL: sexti16_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: ret
+ %shl = shl i32 %a, 16
+ %shr = ashr exact i32 %shl, 16
+ ret i32 %shr
+}
+
+define i32 @sexti16_i32_2(i16 %a) {
+; CHECK-LABEL: sexti16_i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: ret
+ %1 = sext i16 %a to i32
+ ret i32 %1
+}
+
+define i64 @sexti1_i64(i64 %a) {
+; CHECK-LABEL: sexti1_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a1, a0, 0, 0
+; CHECK-NEXT: mv a0, a1
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 63
+ %shr = ashr exact i64 %shl, 63
+ ret i64 %shr
+}
+
+define i64 @sexti1_i64_2(i1 %a) {
+; CHECK-LABEL: sexti1_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a1, a0, 0, 0
+; CHECK-NEXT: mv a0, a1
+; CHECK-NEXT: ret
+ %1 = sext i1 %a to i64
+ ret i64 %1
+}
+
+define i64 @sexti8_i64(i64 %a) {
+; CHECK-LABEL: sexti8_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 56
+ %shr = ashr exact i64 %shl, 56
+ ret i64 %shr
+}
+
+define i64 @sexti8_i64_2(i8 %a) {
+; CHECK-LABEL: sexti8_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: ret
+ %1 = sext i8 %a to i64
+ ret i64 %1
+}
+
+define i64 @sexti16_i64(i64 %a) {
+; CHECK-LABEL: sexti16_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 48
+ %shr = ashr exact i64 %shl, 48
+ ret i64 %shr
+}
+
+define i64 @sexti16_i64_2(i16 %a) {
+; CHECK-LABEL: sexti16_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: ret
+ %1 = sext i16 %a to i64
+ ret i64 %1
+}
+
+define i64 @sexti32_i64(i64 %a) {
+; CHECK-LABEL: sexti32_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $x11 killed $x10
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 32
+ %shr = ashr exact i64 %shl, 32
+ ret i64 %shr
+}
+
+define i64 @sexti32_i64_2(i32 %a) {
+; CHECK-LABEL: sexti32_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: srai a1, a0, 31
+; CHECK-NEXT: ret
+ %1 = sext i32 %a to i64
+ ret i64 %1
+}
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
new file mode 100644
index 0000000000000..9cc95ce886133
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -0,0 +1,135 @@
+; 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 signext i32 @sexti1_i32(i32 signext %a) {
+; CHECK-LABEL: sexti1_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %shl = shl i32 %a, 31
+ %shr = ashr exact i32 %shl, 31
+ ret i32 %shr
+}
+
+define signext i32 @sexti1_i32_2(i1 %a) {
+; CHECK-LABEL: sexti1_i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %1 = sext i1 %a to i32
+ ret i32 %1
+}
+
+define signext i32 @sexti8_i32(i32 signext %a) {
+; CHECK-LABEL: sexti8_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: ret
+ %shl = shl i32 %a, 24
+ %shr = ashr exact i32 %shl, 24
+ ret i32 %shr
+}
+
+define signext i32 @sexti8_i32_2(i8 %a) {
+; CHECK-LABEL: sexti8_i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: ret
+ %1 = sext i8 %a to i32
+ ret i32 %1
+}
+
+define signext i32 @sexti16_i32(i32 signext %a) {
+; CHECK-LABEL: sexti16_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: ret
+ %shl = shl i32 %a, 16
+ %shr = ashr exact i32 %shl, 16
+ ret i32 %shr
+}
+
+define signext i32 @sexti16_i32_2(i16 %a) {
+; CHECK-LABEL: sexti16_i32_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: ret
+ %1 = sext i16 %a to i32
+ ret i32 %1
+}
+
+define i64 @sexti1_i64(i64 %a) {
+; CHECK-LABEL: sexti1_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 63
+ %shr = ashr exact i64 %shl, 63
+ ret i64 %shr
+}
+
+define i64 @sexti1_i64_2(i1 %a) {
+; CHECK-LABEL: sexti1_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %1 = sext i1 %a to i64
+ ret i64 %1
+}
+
+define i64 @sexti8_i64(i64 %a) {
+; CHECK-LABEL: sexti8_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 56
+ %shr = ashr exact i64 %shl, 56
+ ret i64 %shr
+}
+
+define i64 @sexti8_i64_2(i8 %a) {
+; CHECK-LABEL: sexti8_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 7, 0
+; CHECK-NEXT: ret
+ %1 = sext i8 %a to i64
+ ret i64 %1
+}
+
+define i64 @sexti16_i64(i64 %a) {
+; CHECK-LABEL: sexti16_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 48
+ %shr = ashr exact i64 %shl, 48
+ ret i64 %shr
+}
+
+define i64 @sexti16_i64_2(i16 %a) {
+; CHECK-LABEL: sexti16_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nds.bfos a0, a0, 15, 0
+; CHECK-NEXT: ret
+ %1 = sext i16 %a to i64
+ ret i64 %1
+}
+
+define i64 @sexti32_i64(i64 %a) {
+; CHECK-LABEL: sexti32_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: sext.w a0, a0
+; CHECK-NEXT: ret
+ %shl = shl i64 %a, 32
+ %shr = ashr exact i64 %shl, 32
+ ret i64 %shr
+}
+
+define i64 @sexti32_i64_2(i32 signext %a) {
+; CHECK-LABEL: sexti32_i64_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: ret
+ %1 = sext i32 %a to i64
+ ret i64 %1
+}
diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index a0238458aff81..6b64144406375 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -2323,8 +2323,8 @@ define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
;
; RV64XANDESPERF-LABEL: sext_ashr_zext_i8:
; RV64XANDESPERF: # %bb.0:
-; RV64XANDESPERF-NEXT: slli a0, a0, 56
-; RV64XANDESPERF-NEXT: srai a0, a0, 31
+; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 7, 0
+; RV64XANDESPERF-NEXT: slli a0, a0, 23
; RV64XANDESPERF-NEXT: srli a0, a0, 32
; RV64XANDESPERF-NEXT: ret
%ext = sext i8 %a to i32
@@ -2472,8 +2472,8 @@ define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
;
; RV64XANDESPERF-LABEL: sext_ashr_zext_i16:
; RV64XANDESPERF: # %bb.0:
-; RV64XANDESPERF-NEXT: slli a0, a0, 48
-; RV64XANDESPERF-NEXT: srai a0, a0, 25
+; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 15, 0
+; RV64XANDESPERF-NEXT: slli a0, a0, 23
; RV64XANDESPERF-NEXT: srli a0, a0, 32
; RV64XANDESPERF-NEXT: ret
%ext = sext i16 %a to i32
>From 2c310fcdbf7d1f23d8df3695a606a6a65356232b Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 14 May 2025 09:21:03 +0800
Subject: [PATCH 2/2] Remove the pattern for sign extending in reg from i32 to
i64
---
llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index 97b25530db242..9ab941d0bda8d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -404,7 +404,6 @@ def NDS_VFPMADB_VF : NDSRVInstVFPMAD<0b000011, "nds.vfpmadb">;
let Predicates = [HasVendorXAndesPerf] in {
-def : Pat<(sext_inreg (XLenVT GPR:$rs1), i32), (NDS_BFOS GPR:$rs1, 31, 0)>;
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (NDS_BFOS GPR:$rs1, 15, 0)>;
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (NDS_BFOS GPR:$rs1, 7, 0)>;
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (NDS_BFOS GPR:$rs1, 0, 0)>;
More information about the llvm-commits
mailing list