[llvm] [RISCV] Add ISel patterns for Xqcia instructions (PR #136548)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 21 02:00:03 PDT 2025
https://github.com/hchandel updated https://github.com/llvm/llvm-project/pull/136548
>From 850bdc72403aa2efa2700a30516e2ccc848ee95c Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Mon, 21 Apr 2025 12:22:35 +0530
Subject: [PATCH 1/3] [RISCV] Add ISel patterns for Xqcia instructions This
patch adds instruction selection patterns for generating the integer
arithmetic instructions.
Change-Id: I544fe4b35403f51d4e2860aca5bae9f7a353167f
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 8 ++
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 13 ++
llvm/test/CodeGen/RISCV/xqcia.ll | 128 ++++++++++++++++++++
3 files changed, 149 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/xqcia.ll
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 98fba9e86e88a..45320d28b9253 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -421,6 +421,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SELECT, XLenVT, Legal);
else if (!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);
+ if (Subtarget.hasVendorXqcia()){
+ setOperationAction(ISD::UADDSAT, MVT::i32, Legal);
+ setOperationAction(ISD::SADDSAT, MVT::i32, Legal);
+ setOperationAction(ISD::USUBSAT, MVT::i32, Legal);
+ setOperationAction(ISD::SSUBSAT, MVT::i32, Legal);
+ setOperationAction(ISD::SSHLSAT, MVT::i32, Legal);
+ setOperationAction(ISD::USHLSAT, MVT::i32, Legal);
+ }
static const unsigned FPLegalNodeTypes[] = {
ISD::FMINNUM, ISD::FMAXNUM, ISD::FMINIMUMNUM,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index bb0818b001d38..741c4ce8f5d1e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1247,6 +1247,10 @@ class PatGprNoX0Simm32NoSimm26<SDPatternOperator OpNode, RVInst48 Inst>
: Pat<(i32 (OpNode (i32 GPRNoX0:$rs1), simm32_nosimm26:$imm)),
(Inst GPRNoX0:$rs1, simm32_nosimm26:$imm)>;
+class PatGprNoX0GprNoX0<SDPatternOperator OpNode, RVInstR Inst>
+ : Pat<(i32 (OpNode (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2))),
+ (Inst GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+
class QC48LdPat<PatFrag LoadOp, RVInst48 Inst>
: Pat<(i32 (LoadOp (AddLike (i32 GPR:$rs1), simm26_nosimm12:$imm26))),
(Inst GPR:$rs1, simm26_nosimm12:$imm26)>;
@@ -1308,5 +1312,14 @@ let Predicates = [HasVendorXqcisls, IsRV32], AddedComplexity = 1 in {
def : QCScaledStPat<store, QC_SRW>;
} // Predicates = [HasVendorXqcisls, IsRV32], AddedComplexity = 1
+let Predicates = [HasVendorXqcia, IsRV32] in {
+def : PatGprNoX0GprNoX0<saddsat, QC_ADDSAT>;
+def : PatGprNoX0GprNoX0<uaddsat, QC_ADDUSAT>;
+def : PatGprNoX0GprNoX0<ssubsat, QC_SUBSAT>;
+def : PatGprNoX0GprNoX0<usubsat, QC_SUBUSAT>;
+def : PatGprNoX0GprNoX0<ushlsat, QC_SHLUSAT>;
+def : PatGprNoX0GprNoX0<sshlsat, QC_SHLSAT>;
+} // Predicates = [HasVendorXqcia, IsRV32]
+
let Predicates = [HasVendorXqciint, IsRV32] in
def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;
diff --git a/llvm/test/CodeGen/RISCV/xqcia.ll b/llvm/test/CodeGen/RISCV/xqcia.ll
new file mode 100644
index 0000000000000..6a353c358d037
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xqcia.ll
@@ -0,0 +1,128 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test that we are able to generate the Xqcia instructions
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32IXQCIA
+
+define i32 @addsat(i32 %a, i32 %b) {
+; RV32I-LABEL: addsat:
+; RV32I: # %bb.0:
+; RV32I-NEXT: mv a2, a0
+; RV32I-NEXT: add a0, a0, a1
+; RV32I-NEXT: slt a2, a0, a2
+; RV32I-NEXT: slti a1, a1, 0
+; RV32I-NEXT: beq a1, a2, .LBB0_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: srai a0, a0, 31
+; RV32I-NEXT: lui a1, 524288
+; RV32I-NEXT: xor a0, a0, a1
+; RV32I-NEXT: .LBB0_2:
+; RV32I-NEXT: ret
+;
+; RV32IXQCIA-LABEL: addsat:
+; RV32IXQCIA: # %bb.0:
+; RV32IXQCIA-NEXT: qc.addsat a0, a0, a1
+; RV32IXQCIA-NEXT: ret
+ %addai = tail call i32 @llvm.sadd.sat.i32(i32 %a,i32 %b)
+ ret i32 %addai
+}
+
+define i32 @addusat(i32 %a, i32 %b) {
+; RV32I-LABEL: addusat:
+; RV32I: # %bb.0:
+; RV32I-NEXT: add a1, a0, a1
+; RV32I-NEXT: sltu a0, a1, a0
+; RV32I-NEXT: neg a0, a0
+; RV32I-NEXT: or a0, a0, a1
+; RV32I-NEXT: ret
+;
+; RV32IXQCIA-LABEL: addusat:
+; RV32IXQCIA: # %bb.0:
+; RV32IXQCIA-NEXT: qc.addusat a0, a0, a1
+; RV32IXQCIA-NEXT: ret
+ %addai = tail call i32 @llvm.uadd.sat.i32(i32 %a,i32 %b)
+ ret i32 %addai
+}
+
+define i32 @subsat(i32 %a, i32 %b) {
+; RV32I-LABEL: subsat:
+; RV32I: # %bb.0:
+; RV32I-NEXT: mv a2, a0
+; RV32I-NEXT: sgtz a3, a1
+; RV32I-NEXT: sub a0, a0, a1
+; RV32I-NEXT: slt a1, a0, a2
+; RV32I-NEXT: beq a3, a1, .LBB2_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: srai a0, a0, 31
+; RV32I-NEXT: lui a1, 524288
+; RV32I-NEXT: xor a0, a0, a1
+; RV32I-NEXT: .LBB2_2:
+; RV32I-NEXT: ret
+;
+; RV32IXQCIA-LABEL: subsat:
+; RV32IXQCIA: # %bb.0:
+; RV32IXQCIA-NEXT: qc.subsat a0, a0, a1
+; RV32IXQCIA-NEXT: ret
+ %addai = tail call i32 @llvm.ssub.sat.i32(i32 %a,i32 %b)
+ ret i32 %addai
+}
+
+define i32 @subusat(i32 %a, i32 %b) {
+; RV32I-LABEL: subusat:
+; RV32I: # %bb.0:
+; RV32I-NEXT: sub a1, a0, a1
+; RV32I-NEXT: sltu a0, a0, a1
+; RV32I-NEXT: addi a0, a0, -1
+; RV32I-NEXT: and a0, a0, a1
+; RV32I-NEXT: ret
+;
+; RV32IXQCIA-LABEL: subusat:
+; RV32IXQCIA: # %bb.0:
+; RV32IXQCIA-NEXT: qc.subusat a0, a0, a1
+; RV32IXQCIA-NEXT: ret
+ %addai = tail call i32 @llvm.usub.sat.i32(i32 %a,i32 %b)
+ ret i32 %addai
+}
+
+define i32 @shlusat(i32 %a, i32 %b) {
+; RV32I-LABEL: shlusat:
+; RV32I: # %bb.0:
+; RV32I-NEXT: sll a2, a0, a1
+; RV32I-NEXT: srl a1, a2, a1
+; RV32I-NEXT: xor a0, a0, a1
+; RV32I-NEXT: seqz a0, a0
+; RV32I-NEXT: addi a0, a0, -1
+; RV32I-NEXT: or a0, a0, a2
+; RV32I-NEXT: ret
+;
+; RV32IXQCIA-LABEL: shlusat:
+; RV32IXQCIA: # %bb.0:
+; RV32IXQCIA-NEXT: qc.shlusat a0, a0, a1
+; RV32IXQCIA-NEXT: ret
+ %addai = tail call i32 @llvm.ushl.sat.i32(i32 %a,i32 %b)
+ ret i32 %addai
+}
+
+define i32 @shlsat(i32 %a, i32 %b) {
+; RV32I-LABEL: shlsat:
+; RV32I: # %bb.0:
+; RV32I-NEXT: mv a2, a0
+; RV32I-NEXT: sll a0, a0, a1
+; RV32I-NEXT: sra a1, a0, a1
+; RV32I-NEXT: beq a2, a1, .LBB5_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: srai a2, a2, 31
+; RV32I-NEXT: lui a0, 524288
+; RV32I-NEXT: addi a0, a0, -1
+; RV32I-NEXT: xor a0, a2, a0
+; RV32I-NEXT: .LBB5_2:
+; RV32I-NEXT: ret
+;
+; RV32IXQCIA-LABEL: shlsat:
+; RV32IXQCIA: # %bb.0:
+; RV32IXQCIA-NEXT: qc.shlsat a0, a0, a1
+; RV32IXQCIA-NEXT: ret
+ %addai = tail call i32 @llvm.sshl.sat.i32(i32 %a,i32 %b)
+ ret i32 %addai
+}
>From 5860e7f04238c6972bf6a183349e7180d1bf7ab5 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Mon, 21 Apr 2025 14:15:21 +0530
Subject: [PATCH 2/3] fixup! Minor changes
Change-Id: I240a028c2fc37f239faa62e1215cd89d79e89e42
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 1 +
llvm/test/CodeGen/RISCV/xqcia.ll | 24 ++++++++++-----------
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 45320d28b9253..d4ca9f48b7aef 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -421,6 +421,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SELECT, XLenVT, Legal);
else if (!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);
+
if (Subtarget.hasVendorXqcia()){
setOperationAction(ISD::UADDSAT, MVT::i32, Legal);
setOperationAction(ISD::SADDSAT, MVT::i32, Legal);
diff --git a/llvm/test/CodeGen/RISCV/xqcia.ll b/llvm/test/CodeGen/RISCV/xqcia.ll
index 6a353c358d037..c75bb9daefcf2 100644
--- a/llvm/test/CodeGen/RISCV/xqcia.ll
+++ b/llvm/test/CodeGen/RISCV/xqcia.ll
@@ -24,8 +24,8 @@ define i32 @addsat(i32 %a, i32 %b) {
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.addsat a0, a0, a1
; RV32IXQCIA-NEXT: ret
- %addai = tail call i32 @llvm.sadd.sat.i32(i32 %a,i32 %b)
- ret i32 %addai
+ %saddsat = tail call i32 @llvm.sadd.sat.i32(i32 %a,i32 %b)
+ ret i32 %saddsat
}
define i32 @addusat(i32 %a, i32 %b) {
@@ -41,8 +41,8 @@ define i32 @addusat(i32 %a, i32 %b) {
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.addusat a0, a0, a1
; RV32IXQCIA-NEXT: ret
- %addai = tail call i32 @llvm.uadd.sat.i32(i32 %a,i32 %b)
- ret i32 %addai
+ %uaddsat = tail call i32 @llvm.uadd.sat.i32(i32 %a,i32 %b)
+ ret i32 %uaddsat
}
define i32 @subsat(i32 %a, i32 %b) {
@@ -64,8 +64,8 @@ define i32 @subsat(i32 %a, i32 %b) {
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.subsat a0, a0, a1
; RV32IXQCIA-NEXT: ret
- %addai = tail call i32 @llvm.ssub.sat.i32(i32 %a,i32 %b)
- ret i32 %addai
+ %ssubsat = tail call i32 @llvm.ssub.sat.i32(i32 %a,i32 %b)
+ ret i32 %ssubsat
}
define i32 @subusat(i32 %a, i32 %b) {
@@ -81,8 +81,8 @@ define i32 @subusat(i32 %a, i32 %b) {
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.subusat a0, a0, a1
; RV32IXQCIA-NEXT: ret
- %addai = tail call i32 @llvm.usub.sat.i32(i32 %a,i32 %b)
- ret i32 %addai
+ %usubsat = tail call i32 @llvm.usub.sat.i32(i32 %a,i32 %b)
+ ret i32 %usubsat
}
define i32 @shlusat(i32 %a, i32 %b) {
@@ -100,8 +100,8 @@ define i32 @shlusat(i32 %a, i32 %b) {
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.shlusat a0, a0, a1
; RV32IXQCIA-NEXT: ret
- %addai = tail call i32 @llvm.ushl.sat.i32(i32 %a,i32 %b)
- ret i32 %addai
+ %ushlsat = tail call i32 @llvm.ushl.sat.i32(i32 %a,i32 %b)
+ ret i32 %ushlsat
}
define i32 @shlsat(i32 %a, i32 %b) {
@@ -123,6 +123,6 @@ define i32 @shlsat(i32 %a, i32 %b) {
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.shlsat a0, a0, a1
; RV32IXQCIA-NEXT: ret
- %addai = tail call i32 @llvm.sshl.sat.i32(i32 %a,i32 %b)
- ret i32 %addai
+ %sshlsat = tail call i32 @llvm.sshl.sat.i32(i32 %a,i32 %b)
+ ret i32 %sshlsat
}
>From 8284d625b99b94d017b0f2b963a831dfaf16842b Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Mon, 21 Apr 2025 14:29:28 +0530
Subject: [PATCH 3/3] fixup! clang format
Change-Id: Iebfd125316008441d23de14c4ceecdcfa0042a97
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d4ca9f48b7aef..d7b78fecd0649 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -422,7 +422,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
else if (!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);
- if (Subtarget.hasVendorXqcia()){
+ if (Subtarget.hasVendorXqcia()) {
setOperationAction(ISD::UADDSAT, MVT::i32, Legal);
setOperationAction(ISD::SADDSAT, MVT::i32, Legal);
setOperationAction(ISD::USUBSAT, MVT::i32, Legal);
More information about the llvm-commits
mailing list