Skip to content

[RISCV] Add ISel patterns for Xqcia instructions #136548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 22, 2025
Merged

Conversation

hchandel
Copy link
Contributor

This patch adds instruction selection patterns for generating the integer
arithmetic instructions.

This patch adds instruction selection patterns for generating the integer
arithmetic instructions.

Change-Id: I544fe4b35403f51d4e2860aca5bae9f7a353167f
Change-Id: I240a028c2fc37f239faa62e1215cd89d79e89e42
@llvmbot
Copy link
Member

llvmbot commented Apr 21, 2025

@llvm/pr-subscribers-backend-risc-v

Author: quic_hchandel (hchandel)

Changes

This patch adds instruction selection patterns for generating the integer
arithmetic instructions.


Full diff: https://github.com/llvm/llvm-project/pull/136548.diff

3 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+9)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+13)
  • (added) llvm/test/CodeGen/RISCV/xqcia.ll (+128)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 98fba9e86e88a..d4ca9f48b7aef 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -422,6 +422,15 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
   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,
       ISD::FMAXIMUMNUM,   ISD::LRINT,          ISD::LLRINT,
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..c75bb9daefcf2
--- /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
+ %saddsat = tail call i32 @llvm.sadd.sat.i32(i32 %a,i32 %b)
+ ret i32 %saddsat
+}
+
+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
+ %uaddsat = tail call i32 @llvm.uadd.sat.i32(i32 %a,i32 %b)
+ ret i32 %uaddsat
+}
+
+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
+ %ssubsat = tail call i32 @llvm.ssub.sat.i32(i32 %a,i32 %b)
+ ret i32 %ssubsat
+}
+
+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
+ %usubsat = tail call i32 @llvm.usub.sat.i32(i32 %a,i32 %b)
+ ret i32 %usubsat
+}
+
+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
+ %ushlsat = tail call i32 @llvm.ushl.sat.i32(i32 %a,i32 %b)
+ ret i32 %ushlsat
+}
+
+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
+ %sshlsat = tail call i32 @llvm.sshl.sat.i32(i32 %a,i32 %b)
+ ret i32 %sshlsat
+}

Copy link

github-actions bot commented Apr 21, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Change-Id: Iebfd125316008441d23de14c4ceecdcfa0042a97
@lenary
Copy link
Member

lenary commented Apr 21, 2025

LGTM!

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Change-Id: Idfea93ec44758557f7539c35b00ed3352c764c4d
Copy link
Contributor

@svs-quic svs-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@hchandel
Copy link
Contributor Author

All Checks have passed. Merging now.

@hchandel hchandel merged commit 8f8853a into llvm:main Apr 22, 2025
11 checks passed
@hchandel hchandel deleted the xqcia_isel branch April 23, 2025 05:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants