Skip to content

Commit

Permalink
[RISCV] Add codegen for the experimental zicond extension
Browse files Browse the repository at this point in the history
This directly matches the codegen for xventanacondops with vt.maskcn =>
czero.nez and vt.maskc => czero.eqz. An additional difference is that
zicond is available on RV32 in addition to RV64 (xventanacondops is RV64
only).

Differential Revision: https://reviews.llvm.org/D147147
  • Loading branch information
asb committed Mar 30, 2023
1 parent 1190a1d commit a755e80
Show file tree
Hide file tree
Showing 5 changed files with 1,784 additions and 225 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -324,7 +324,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
if (Subtarget.is64Bit())
setOperationAction(ISD::ABS, MVT::i32, Custom);

if (!Subtarget.hasVendorXVentanaCondOps() &&
if (!Subtarget.hasStdExtZicond() && !Subtarget.hasVendorXVentanaCondOps() &&
!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);

Expand Down
36 changes: 36 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZicond.td
Expand Up @@ -23,3 +23,39 @@ def CZERO_EQZ : ALU_rr<0b0000111, 0b101, "czero.eqz">,
def CZERO_NEZ : ALU_rr<0b0000111, 0b111, "czero.nez">,
Sched<[WriteIALU, ReadIALU, ReadIALU]>;
} // Predicates = [HasStdExtZicond]

//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZicond] in {
// Directly use CZERO_EQZ/CZERO_NEZ in case of any of the operands being 0.
def : Pat<(select GPR:$rc, GPR:$rs1, 0),
(CZERO_EQZ GPR:$rs1, GPR:$rc)>;
def : Pat<(select GPR:$rc, 0, GPR:$rs1),
(CZERO_NEZ GPR:$rs1, GPR:$rc)>;

def : Pat<(select (riscv_setne GPR:$rc), GPR:$rs1, 0),
(CZERO_EQZ GPR:$rs1, GPR:$rc)>;
def : Pat<(select (riscv_seteq GPR:$rc), GPR:$rs1, 0),
(CZERO_NEZ GPR:$rs1, GPR:$rc)>;
def : Pat<(select (riscv_setne GPR:$rc), 0, GPR:$rs1),
(CZERO_NEZ GPR:$rs1, GPR:$rc)>;
def : Pat<(select (riscv_seteq GPR:$rc), 0, GPR:$rs1),
(CZERO_EQZ GPR:$rs1, GPR:$rc)>;

// Conditional AND operation patterns.
def : Pat<(select GPR:$rc, (and GPR:$rs1, GPR:$rs2), GPR:$rs1),
(OR (AND $rs1, $rs2), (CZERO_NEZ $rs1, $rc))>;
def : Pat<(select GPR:$rc, GPR:$rs1, (and GPR:$rs1, GPR:$rs2)),
(OR (AND $rs1, $rs2), (CZERO_EQZ $rs1, $rc))>;

// Basic select pattern that selects between 2 registers.
def : Pat<(select GPR:$rc, GPR:$rs1, GPR:$rs2),
(OR (CZERO_EQZ $rs1, $rc), (CZERO_NEZ $rs2, $rc))>;

def : Pat<(select (riscv_setne GPR:$rc), GPR:$rs1, GPR:$rs2),
(OR (CZERO_EQZ GPR:$rs1, GPR:$rc), (CZERO_NEZ GPR:$rs2, GPR:$rc))>;
def : Pat<(select (riscv_seteq GPR:$rc), GPR:$rs2, GPR:$rs1),
(OR (CZERO_EQZ GPR:$rs1, GPR:$rc), (CZERO_NEZ GPR:$rs2, GPR:$rc))>;
} // Predicates = [HasStdExtZicond]

0 comments on commit a755e80

Please sign in to comment.