-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[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
Conversation
This patch adds instruction selection patterns for generating the integer arithmetic instructions. Change-Id: I544fe4b35403f51d4e2860aca5bae9f7a353167f
Change-Id: I240a028c2fc37f239faa62e1215cd89d79e89e42
@llvm/pr-subscribers-backend-risc-v Author: quic_hchandel (hchandel) ChangesThis patch adds instruction selection patterns for generating the integer Full diff: https://github.com/llvm/llvm-project/pull/136548.diff 3 Files Affected:
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
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Change-Id: Iebfd125316008441d23de14c4ceecdcfa0042a97
LGTM! |
There was a problem hiding this 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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
All Checks have passed. Merging now. |
This patch adds instruction selection patterns for generating the integer
arithmetic instructions.