-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[RISCV] Add ISel patterns for Qualcomm uC Xqcicm extension #145643
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
Change-Id: I85ca9b02f88b34c3745a28aebc73d6da80928207
@llvm/pr-subscribers-backend-risc-v Author: quic_hchandel (hchandel) ChangesAdd codegen patterns for the conditional move instructions in this extension Patch is 36.15 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/145643.diff 4 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 712f6154732a2..bb26306d19a20 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -436,7 +436,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ABS, MVT::i32, Custom);
}
- if (!Subtarget.useCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov())
+ if (!Subtarget.useCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov() &&
+ !Subtarget.hasVendorXqcicm())
setOperationAction(ISD::SELECT, XLenVT, Custom);
if (Subtarget.hasVendorXqcia() && !Subtarget.is64Bit()) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index ccd20859c24e6..a306e7e9fc542 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1335,6 +1335,14 @@ class QCScaledStPat<PatFrag StoreOp, RVInst Inst>
: Pat<(StoreOp (i32 GPR:$rd), (AddShl (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt)),
(Inst GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>;
+class QCIMVCCPat<CondCode Cond, QCIMVCC Inst>
+ : Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), (XLenVT GPRNoX0:$rs2), Cond)), (XLenVT GPRNoX0:$rs3), (XLenVT GPRNoX0:$rd)),
+ (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs3)>;
+
+class QCIMVCCIPat<CondCode Cond, QCIMVCCI Inst>
+ : Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), simm5:$imm, Cond)), (XLenVT GPRNoX0:$rs3), (XLenVT GPRNoX0:$rd)),
+ (Inst GPRNoX0:$rd, GPRNoX0:$rs1, simm5:$imm, GPRNoX0:$rs3)>;
+
// Match `riscv_brcc` and lower to the appropriate XQCIBI branch instruction.
class BcciPat<CondCode Cond, QCIBranchInst_rii Inst, DAGOperand InTyImm>
: Pat<(riscv_brcc (XLenVT GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12),
@@ -1469,6 +1477,20 @@ def: Pat<(i32 (ctlz (not (i32 GPR:$rs1)))), (QC_CLO GPR:$rs1)>;
let Predicates = [HasVendorXqciint, IsRV32] in
def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;
+let Predicates = [HasVendorXqcicm, IsRV32] in {
+def : Pat<(select (XLenVT GPRNoX0:$cond), (XLenVT GPRNoX0:$a),(XLenVT GPRNoX0:$b)),
+ (QC_MVEQI GPRNoX0:$a, GPRNoX0:$cond, (XLenVT 0), GPRNoX0:$b)>;
+
+def : QCIMVCCPat <SETEQ, QC_MVEQ>;
+def : QCIMVCCPat <SETNE, QC_MVNE>;
+def : QCIMVCCPat <SETLT, QC_MVLT>;
+def : QCIMVCCPat <SETULT, QC_MVLTU>;
+
+def : QCIMVCCIPat <SETEQ, QC_MVEQI>;
+def : QCIMVCCIPat <SETNE, QC_MVNEI>;
+def : QCIMVCCIPat <SETLT, QC_MVLTI>;
+def : QCIMVCCIPat <SETULT, QC_MVLTUI>;
+}
//===----------------------------------------------------------------------===/i
// Compress Instruction tablegen backend.
diff --git a/llvm/test/CodeGen/RISCV/select-cond.ll b/llvm/test/CodeGen/RISCV/select-cond.ll
index a5f4677f73f13..d9f9ad379ee95 100644
--- a/llvm/test/CodeGen/RISCV/select-cond.ll
+++ b/llvm/test/CodeGen/RISCV/select-cond.ll
@@ -3,6 +3,8 @@
; RUN: | FileCheck %s --check-prefixes=RV32
; RUN: llc -mtriple=riscv32 -mattr=+xtheadcondmov -verify-machineinstrs < %s \
; RUN: | FileCheck %s --check-prefixes=RV32-THEAD
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32-XQCICM
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck %s --check-prefixes=RV64
; RUN: llc -mtriple=riscv64 -mattr=+xmipscmov -verify-machineinstrs < %s \
@@ -26,6 +28,13 @@ define signext i32 @select_i32_trunc(i32 signext %cond, i32 signext %x, i32 sign
; RV32-THEAD-NEXT: mv a0, a1
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_trunc:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: andi a0, a0, 1
+; RV32-XQCICM-NEXT: qc.mveqi a1, a0, 0, a2
+; RV32-XQCICM-NEXT: mv a0, a1
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_trunc:
; RV64: # %bb.0:
; RV64-NEXT: andi a3, a0, 1
@@ -64,6 +73,13 @@ define signext i32 @select_i32_param(i1 signext %cond, i32 signext %x, i32 signe
; RV32-THEAD-NEXT: mv a0, a1
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_param:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: andi a0, a0, 1
+; RV32-XQCICM-NEXT: qc.mveqi a1, a0, 0, a2
+; RV32-XQCICM-NEXT: mv a0, a1
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_param:
; RV64: # %bb.0:
; RV64-NEXT: andi a3, a0, 1
@@ -100,6 +116,12 @@ define signext i32 @select_i32_eq(i32 signext %a, i32 signext %b, i32 signext %x
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_eq:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mveq a3, a0, a1, a2
+; RV32-XQCICM-NEXT: mv a0, a3
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_eq:
; RV64: # %bb.0:
; RV64-NEXT: beq a0, a1, .LBB2_2
@@ -136,6 +158,12 @@ define signext i32 @select_i32_ne(i32 signext %a, i32 signext %b, i32 signext %x
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_ne:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvne a3, a0, a1, a2
+; RV32-XQCICM-NEXT: mv a0, a3
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_ne:
; RV64: # %bb.0:
; RV64-NEXT: bne a0, a1, .LBB3_2
@@ -172,6 +200,12 @@ define signext i32 @select_i32_ugt(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_ugt:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvltu a3, a1, a0, a2
+; RV32-XQCICM-NEXT: mv a0, a3
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_ugt:
; RV64: # %bb.0:
; RV64-NEXT: bltu a1, a0, .LBB4_2
@@ -208,6 +242,12 @@ define signext i32 @select_i32_uge(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_uge:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvltu a2, a0, a1, a3
+; RV32-XQCICM-NEXT: mv a0, a2
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_uge:
; RV64: # %bb.0:
; RV64-NEXT: bgeu a0, a1, .LBB5_2
@@ -244,6 +284,12 @@ define signext i32 @select_i32_ult(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_ult:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvltu a3, a0, a1, a2
+; RV32-XQCICM-NEXT: mv a0, a3
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_ult:
; RV64: # %bb.0:
; RV64-NEXT: bltu a0, a1, .LBB6_2
@@ -280,6 +326,12 @@ define signext i32 @select_i32_ule(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_ule:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvltu a2, a1, a0, a3
+; RV32-XQCICM-NEXT: mv a0, a2
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_ule:
; RV64: # %bb.0:
; RV64-NEXT: bgeu a1, a0, .LBB7_2
@@ -316,6 +368,12 @@ define signext i32 @select_i32_sgt(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_sgt:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvlt a3, a1, a0, a2
+; RV32-XQCICM-NEXT: mv a0, a3
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_sgt:
; RV64: # %bb.0:
; RV64-NEXT: blt a1, a0, .LBB8_2
@@ -352,6 +410,12 @@ define signext i32 @select_i32_sge(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_sge:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvlt a2, a0, a1, a3
+; RV32-XQCICM-NEXT: mv a0, a2
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_sge:
; RV64: # %bb.0:
; RV64-NEXT: bge a0, a1, .LBB9_2
@@ -388,6 +452,12 @@ define signext i32 @select_i32_slt(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_slt:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvlt a3, a0, a1, a2
+; RV32-XQCICM-NEXT: mv a0, a3
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_slt:
; RV64: # %bb.0:
; RV64-NEXT: blt a0, a1, .LBB10_2
@@ -424,6 +494,12 @@ define signext i32 @select_i32_sle(i32 signext %a, i32 signext %b, i32 signext %
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i32_sle:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: qc.mvlt a2, a1, a0, a3
+; RV32-XQCICM-NEXT: mv a0, a2
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i32_sle:
; RV64: # %bb.0:
; RV64-NEXT: bge a1, a0, .LBB11_2
@@ -465,6 +541,15 @@ define i64 @select_i64_trunc(i64 %cond, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a0, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_trunc:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: mv a1, a3
+; RV32-XQCICM-NEXT: andi a0, a0, 1
+; RV32-XQCICM-NEXT: qc.mveqi a2, a0, 0, a4
+; RV32-XQCICM-NEXT: qc.mveqi a1, a0, 0, a5
+; RV32-XQCICM-NEXT: mv a0, a2
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_trunc:
; RV64: # %bb.0:
; RV64-NEXT: andi a3, a0, 1
@@ -507,6 +592,15 @@ define i64 @select_i64_param(i1 %cond, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a2
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_param:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: andi a0, a0, 1
+; RV32-XQCICM-NEXT: qc.mveqi a1, a0, 0, a3
+; RV32-XQCICM-NEXT: qc.mveqi a2, a0, 0, a4
+; RV32-XQCICM-NEXT: mv a0, a1
+; RV32-XQCICM-NEXT: mv a1, a2
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_param:
; RV64: # %bb.0:
; RV64-NEXT: andi a3, a0, 1
@@ -552,6 +646,17 @@ define i64 @select_i64_eq(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_eq:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: xor a1, a1, a3
+; RV32-XQCICM-NEXT: xor a0, a0, a2
+; RV32-XQCICM-NEXT: or a0, a0, a1
+; RV32-XQCICM-NEXT: qc.mveqi a6, a0, 0, a4
+; RV32-XQCICM-NEXT: qc.mveqi a7, a0, 0, a5
+; RV32-XQCICM-NEXT: mv a0, a6
+; RV32-XQCICM-NEXT: mv a1, a7
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_eq:
; RV64: # %bb.0:
; RV64-NEXT: beq a0, a1, .LBB14_2
@@ -597,6 +702,17 @@ define i64 @select_i64_ne(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_ne:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: xor a1, a1, a3
+; RV32-XQCICM-NEXT: xor a0, a0, a2
+; RV32-XQCICM-NEXT: or a0, a0, a1
+; RV32-XQCICM-NEXT: qc.mvnei a6, a0, 0, a4
+; RV32-XQCICM-NEXT: qc.mvnei a7, a0, 0, a5
+; RV32-XQCICM-NEXT: mv a0, a6
+; RV32-XQCICM-NEXT: mv a1, a7
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_ne:
; RV64: # %bb.0:
; RV64-NEXT: bne a0, a1, .LBB15_2
@@ -647,6 +763,17 @@ define i64 @select_i64_ugt(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_ugt:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a2, a0
+; RV32-XQCICM-NEXT: sltu a2, a3, a1
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a4, a2, 0, a6
+; RV32-XQCICM-NEXT: qc.mveqi a5, a2, 0, a7
+; RV32-XQCICM-NEXT: mv a0, a4
+; RV32-XQCICM-NEXT: mv a1, a5
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_ugt:
; RV64: # %bb.0:
; RV64-NEXT: bltu a1, a0, .LBB16_2
@@ -697,6 +824,17 @@ define i64 @select_i64_uge(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_uge:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a0, a2
+; RV32-XQCICM-NEXT: sltu a2, a1, a3
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a6, a2, 0, a4
+; RV32-XQCICM-NEXT: qc.mveqi a7, a2, 0, a5
+; RV32-XQCICM-NEXT: mv a0, a6
+; RV32-XQCICM-NEXT: mv a1, a7
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_uge:
; RV64: # %bb.0:
; RV64-NEXT: bgeu a0, a1, .LBB17_2
@@ -747,6 +885,17 @@ define i64 @select_i64_ult(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_ult:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a0, a2
+; RV32-XQCICM-NEXT: sltu a2, a1, a3
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a4, a2, 0, a6
+; RV32-XQCICM-NEXT: qc.mveqi a5, a2, 0, a7
+; RV32-XQCICM-NEXT: mv a0, a4
+; RV32-XQCICM-NEXT: mv a1, a5
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_ult:
; RV64: # %bb.0:
; RV64-NEXT: bltu a0, a1, .LBB18_2
@@ -797,6 +946,17 @@ define i64 @select_i64_ule(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_ule:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a2, a0
+; RV32-XQCICM-NEXT: sltu a2, a3, a1
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a6, a2, 0, a4
+; RV32-XQCICM-NEXT: qc.mveqi a7, a2, 0, a5
+; RV32-XQCICM-NEXT: mv a0, a6
+; RV32-XQCICM-NEXT: mv a1, a7
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_ule:
; RV64: # %bb.0:
; RV64-NEXT: bgeu a1, a0, .LBB19_2
@@ -847,6 +1007,17 @@ define i64 @select_i64_sgt(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_sgt:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a2, a0
+; RV32-XQCICM-NEXT: slt a2, a3, a1
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a4, a2, 0, a6
+; RV32-XQCICM-NEXT: qc.mveqi a5, a2, 0, a7
+; RV32-XQCICM-NEXT: mv a0, a4
+; RV32-XQCICM-NEXT: mv a1, a5
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_sgt:
; RV64: # %bb.0:
; RV64-NEXT: blt a1, a0, .LBB20_2
@@ -897,6 +1068,17 @@ define i64 @select_i64_sge(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_sge:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a0, a2
+; RV32-XQCICM-NEXT: slt a2, a1, a3
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a6, a2, 0, a4
+; RV32-XQCICM-NEXT: qc.mveqi a7, a2, 0, a5
+; RV32-XQCICM-NEXT: mv a0, a6
+; RV32-XQCICM-NEXT: mv a1, a7
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_sge:
; RV64: # %bb.0:
; RV64-NEXT: bge a0, a1, .LBB21_2
@@ -947,6 +1129,17 @@ define i64 @select_i64_slt(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_slt:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a0, a2
+; RV32-XQCICM-NEXT: slt a2, a1, a3
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a4, a2, 0, a6
+; RV32-XQCICM-NEXT: qc.mveqi a5, a2, 0, a7
+; RV32-XQCICM-NEXT: mv a0, a4
+; RV32-XQCICM-NEXT: mv a1, a5
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_slt:
; RV64: # %bb.0:
; RV64-NEXT: blt a0, a1, .LBB22_2
@@ -997,6 +1190,17 @@ define i64 @select_i64_sle(i64 %a, i64 %b, i64 %x, i64 %y) nounwind {
; RV32-THEAD-NEXT: mv a1, a5
; RV32-THEAD-NEXT: ret
;
+; RV32-XQCICM-LABEL: select_i64_sle:
+; RV32-XQCICM: # %bb.0:
+; RV32-XQCICM-NEXT: sltu a0, a2, a0
+; RV32-XQCICM-NEXT: slt a2, a3, a1
+; RV32-XQCICM-NEXT: qc.mveq a2, a1, a3, a0
+; RV32-XQCICM-NEXT: qc.mveqi a6, a2, 0, a4
+; RV32-XQCICM-NEXT: qc.mveqi a7, a2, 0, a5
+; RV32-XQCICM-NEXT: mv a0, a6
+; RV32-XQCICM-NEXT: mv a1, a7
+; RV32-XQCICM-NEXT: ret
+;
; RV64-LABEL: select_i64_sle:
; RV64: # %bb.0:
; RV64-NEXT: bge a1, a0, .LBB23_2
diff --git a/llvm/test/CodeGen/RISCV/xqcicm.ll b/llvm/test/CodeGen/RISCV/xqcicm.ll
new file mode 100644
index 0000000000000..4adb3dce265d1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xqcicm.ll
@@ -0,0 +1,679 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test that we are able to generate the Xqcicm instructions
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32IXQCICM
+
+define i32 @select_example(i32 %cond, i32 %x, i32 %y) {
+; RV32I-LABEL: select_example:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: andi a3, a0, 1
+; RV32I-NEXT: mv a0, a1
+; RV32I-NEXT: bnez a3, .LBB0_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: mv a0, a2
+; RV32I-NEXT: .LBB0_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICM-LABEL: select_example:
+; RV32IXQCICM: # %bb.0: # %entry
+; RV32IXQCICM-NEXT: andi a0, a0, 1
+; RV32IXQCICM-NEXT: qc.mveqi a1, a0, 0, a2
+; RV32IXQCICM-NEXT: mv a0, a1
+; RV32IXQCICM-NEXT: ret
+entry:
+ %cond_trunc = trunc i32 %cond to i1
+ %sel = select i1 %cond_trunc, i32 %x, i32 %y
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_eq(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_eq:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a1, 11
+; RV32I-NEXT: beq a0, a1, .LBB1_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: mv a2, a3
+; RV32I-NEXT: .LBB1_2: # %entry
+; RV32I-NEXT: mv a0, a2
+; RV32I-NEXT: ret
+;
+; RV32IXQCICM-LABEL: select_cc_example_eq:
+; RV32IXQCICM: # %bb.0: # %entry
+; RV32IXQCICM-NEXT: qc.mveqi a3, a0, 11, a2
+; RV32IXQCICM-NEXT: mv a0, a3
+; RV32IXQCICM-NEXT: ret
+entry:
+ %cmp = icmp eq i32 %a, 11
+ %sel = select i1 %cmp, i32 %x, i32 %y
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_eq1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_eq1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a1, 11
+; RV32I-NEXT: beq a0, a1, .LBB2_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: mv a2, a3
+; RV32I-NEXT: .LBB2_2: # %entry
+; RV32I-NEXT: mv a0, a2
+; RV32I-NEXT: ret
+;
+; RV32IXQCICM-LABEL: select_cc_example_eq1:
+; RV32IXQCICM: # %bb.0: # %entry
+; RV32IXQCICM-NEXT: qc.mveqi a3, a0, 11, a2
+; RV32IXQCICM-NEXT: mv a0, a3
+; RV32IXQCICM-NEXT: ret
+entry:
+ %cmp = icmp eq i32 11, %a
+ %sel = select i1 %cmp, i32 %x, i32 %y
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ne(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ne:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a1, 11
+; RV32I-NEXT: bne a0, a1, .LBB3_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: mv a2, a3
+; RV32I-NEXT: .LBB3_2: # %entry
+; RV32I-NEXT: mv a0, a2
+; RV32I-NEXT: ret
+;
+; RV32IXQCICM-LABEL: select_cc_example_ne:
+; RV32IXQCICM: # %bb.0: # %entry
+; RV32IXQCICM-NEXT: qc.mvnei a3, a0, 11, a2
+; RV32IXQCICM-NEXT: mv a0, a3
+; RV32IXQCICM-NEXT: ret
+entry:
+ %cmp = icmp ne i32 %a, 11
+ %sel = select i1 %cmp, i32 %x, i32 %y
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ne1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ne1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a1, 11
+; RV32I-NEXT: bne a0, a1, .LBB4_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: mv a2, a3
+; RV32I-NEXT: .LBB4_2: # %entry
+; RV32I-NEXT: mv a0, a2
+; RV32I-NEXT: ret
+;
+; RV32IXQCICM-LABEL: select_cc_example_ne1:
+; RV32IXQCICM: # %bb.0: # %entry
+; RV32IXQCICM-NEXT: qc.mvnei a3, a0, 11, a2
+; RV32IXQCICM-NEXT: mv a0, a3
+; RV32IXQCICM-NEXT: ret
+entry:
+ %cmp = icmp ne i32 11, %a
+ %sel = select i1 %cmp, i32 %x, i32 %y
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_slt(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_slt:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a1, 11
+; RV32I-NEXT: blt a0, a1, .LBB5_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: mv a2, a3
+; RV32I-NEXT: .LBB5_2: # %entry
+; RV32I-NEXT: mv a0...
[truncated]
|
Will you be adding commuting support for the rd/rs3 sources? That should avoid some copies if rs3 is a better match for the destination register. |
Change-Id: I3f8b9ef7f6a0b2ccc098743086412f1b39eb6639
I will do that in a follow-up PR. |
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
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!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/25482 Here is the relevant piece of the build log for the reference
|
Add codegen patterns for the conditional move instructions in this extension
Add codegen patterns for the conditional move instructions in this extension