Skip to content

Commit

Permalink
[RISCV] Implement Alu Intrinsics
Browse files Browse the repository at this point in the history
  • Loading branch information
realqhc committed Jul 20, 2023
1 parent 100e72b commit 1442f85
Show file tree
Hide file tree
Showing 5 changed files with 521 additions and 1 deletion.
32 changes: 32 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsRISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -1771,4 +1771,36 @@ def int_riscv_cv_mac_machhsrn : ScalarCoreVMacGprGprGprImmIntrinsic;

def int_riscv_cv_elw_elw
: Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly]>;

class ScalarCoreVAluGprIntrinsic
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty],
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
class ScalarCoreVAluGprGprIntrinsic
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
class ScalarCoreVAluGprGprGprIntrinsic
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
def int_riscv_cv_alu_abs : ScalarCoreVAluGprIntrinsic;
def int_riscv_cv_alu_slet : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_sletu : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_min : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_minu : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_max : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_maxu : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_exths : ScalarCoreVAluGprIntrinsic;
def int_riscv_cv_alu_exthz : ScalarCoreVAluGprIntrinsic;
def int_riscv_cv_alu_extbs : ScalarCoreVAluGprIntrinsic;
def int_riscv_cv_alu_extbz : ScalarCoreVAluGprIntrinsic;

def int_riscv_cv_alu_clip : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_clipu : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_addn : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_alu_addun : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_alu_addrn : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_alu_addurn : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_alu_subn : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_alu_subun : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_alu_subrn : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_alu_suburn : ScalarCoreVAluGprGprGprIntrinsic;
} // TargetPrefix = "riscv"
3 changes: 2 additions & 1 deletion llvm/lib/Support/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
{"xcvbitmanip", RISCVExtensionVersion{1, 0}},
{"xcvbi", RISCVExtensionVersion{1, 0}},
{"xcvmac", RISCVExtensionVersion{1, 0}},
{"xcvelw", RISCVExtensionVersion{1, 0}}
{"xcvelw", RISCVExtensionVersion{1, 0}},
{"xcvalu", RISCVExtensionVersion{1, 0}}
};

static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
Expand Down
95 changes: 95 additions & 0 deletions llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class RISCVExpandPseudo : public MachineFunctionPass {
bool expandVRELOAD(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
bool expandCoreVShuffle(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
bool expandCoreVBitManip(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
bool expandCoreVClip(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
bool expandCoreVAddSub(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
};

char RISCVExpandPseudo::ID = 0;
Expand Down Expand Up @@ -142,6 +144,18 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
case RISCV::CV_BCLR_PSEUDO:
case RISCV::CV_INSERT_PSEUDO:
return expandCoreVBitManip(MBB, MBBI);
case RISCV::CV_CLIP_PSEUDO:
case RISCV::CV_CLIPU_PSEUDO:
return expandCoreVClip(MBB, MBBI);
case RISCV::CV_ADDN_PSEUDO:
case RISCV::CV_ADDUN_PSEUDO:
case RISCV::CV_ADDRN_PSEUDO:
case RISCV::CV_ADDURN_PSEUDO:
case RISCV::CV_SUBN_PSEUDO:
case RISCV::CV_SUBUN_PSEUDO:
case RISCV::CV_SUBRN_PSEUDO:
case RISCV::CV_SUBURN_PSEUDO:
return expandCoreVAddSub(MBB, MBBI);
}

return false;
Expand Down Expand Up @@ -395,6 +409,87 @@ bool RISCVExpandPseudo::expandCoreVBitManip(MachineBasicBlock &MBB,
return true;
}

bool RISCVExpandPseudo::expandCoreVClip(llvm::MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI) {
DebugLoc DL = MBBI->getDebugLoc();
Register DstReg = MBBI->getOperand(0).getReg();
Register I = MBBI->getOperand(1).getReg();
uint64_t J = MBBI->getOperand(2).getImm();

unsigned Opcode;
switch (MBBI->getOpcode()) {
case RISCV::CV_CLIPU_PSEUDO:
Opcode = RISCV::CV_CLIPU;
break;
case RISCV::CV_CLIP_PSEUDO:
Opcode = RISCV::CV_CLIP;
break;
default:
llvm_unreachable("unknown instruction");
}
const MCInstrDesc &Desc = TII->get(Opcode);
BuildMI(MBB, MBBI, DL, Desc, DstReg).
addReg(I).
addImm(Log2_32_Ceil(J + 1) + 1);
MBBI->eraseFromParent();
return true;
}

bool RISCVExpandPseudo::expandCoreVAddSub(llvm::MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI) {
auto *MRI = &MBB.getParent()->getRegInfo();
DebugLoc DL = MBBI->getDebugLoc();
Register DstReg = MBBI->getOperand(0).getReg();
Register X = MBBI->getOperand(1).getReg();
Register Y = MBBI->getOperand(2).getReg();
uint8_t Shift = MBBI->getOperand(3).getImm();

bool IsImm = 0 <= Shift && Shift <= 31;
unsigned Opcode;
switch (MBBI->getOpcode()) {
case RISCV::CV_ADDN_PSEUDO:
Opcode = IsImm ? RISCV::CV_ADDN : RISCV::CV_ADDNR;
break;
case RISCV::CV_ADDUN_PSEUDO:
Opcode = IsImm ? RISCV::CV_ADDUN : RISCV::CV_ADDUNR;
break;
case RISCV::CV_ADDRN_PSEUDO:
Opcode = IsImm ? RISCV::CV_ADDRN : RISCV::CV_ADDRNR;
break;
case RISCV::CV_ADDURN_PSEUDO:
Opcode = IsImm ? RISCV::CV_ADDURN : RISCV::CV_ADDURNR;
break;
case RISCV::CV_SUBN_PSEUDO:
Opcode = IsImm ? RISCV::CV_SUBN : RISCV::CV_SUBNR;
break;
case RISCV::CV_SUBUN_PSEUDO:
Opcode = IsImm ? RISCV::CV_SUBUN : RISCV::CV_SUBUNR;
break;
case RISCV::CV_SUBRN_PSEUDO:
Opcode = IsImm ? RISCV::CV_SUBRN : RISCV::CV_SUBRNR;
break;
case RISCV::CV_SUBURN_PSEUDO:
Opcode = IsImm ? RISCV::CV_SUBURN : RISCV::CV_SUBURNR;
break;
default:
llvm_unreachable("unknown instruction");
}
const MCInstrDesc &Desc = TII->get(Opcode);
if (IsImm) {
BuildMI(MBB, MBBI, DL, Desc, DstReg).
addReg(X).
addReg(Y).
addImm(Shift);
} else {
MRI->replaceRegWith(DstReg, X);
BuildMI(MBB, MBBI, DL, Desc, DstReg).
addReg(Y).
addReg(DstReg);
}
MBBI->eraseFromParent();
return true;
}

class RISCVPreRAExpandPseudo : public MachineFunctionPass {
public:
const RISCVInstrInfo *TII;
Expand Down
48 changes: 48 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoCOREV.td
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ def cv_tuimm5: Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]>;
def cv_uimm10: Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<10>(Imm);}]>;
def cv_tuimm10: Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<10>(Imm);}]>;

def cv_uimm32: Operand<XLenVT>,
ImmLeaf<XLenVT, [{return isPowerOf2_32(Imm + 1);}]>;


//===----------------------------------------------------------------------===//
// CORE-V specific instructions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -797,6 +801,27 @@ let Predicates = [HasExtXcvmac] in {
// Patterns for general ALU operations
//===----------------------------------------------------------------------===//

class PatCoreVAluGpr <string intr, string asm> :
PatGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
!cast<RVInst>("CV_" # asm)>;
class PatCoreVAluGprGpr <string intr, string asm> :
PatGprGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
!cast<RVInst>("CV_" # asm)>;
multiclass PatCoreVAluGprImm <Intrinsic intr> {
def "CV_" # NAME # "_PSEUDO" :
Pseudo<(outs GPR:$rd), (ins GPR:$rs, cv_uimm32:$imm), []>;
def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
def : PatGprImm<intr, !cast<RVInst>("CV_" # NAME # "_PSEUDO"), cv_uimm32>;
}
multiclass PatCoreVAluGprGprImm <Intrinsic intr> {
def "CV_" # NAME # "_PSEUDO" :
Pseudo<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2, uimm5:$imm), []>;
def : Pat<(intr GPR:$rs1, GPR:$rs2, GPR:$rs3),
(!cast<RVInst>("CV_" # NAME # "R") GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(intr GPR:$rs1, GPR:$rs2, uimm5:$imm),
(!cast<RVInst>("CV_" # NAME # "_PSEUDO") GPR:$rs1, GPR:$rs2, uimm5:$imm)>;
}

let Predicates = [HasExtXcvalu] in {

def : Pat<(abs GPR:$rs1), (CV_ABS GPR:$rs1)>;
Expand Down Expand Up @@ -856,6 +881,29 @@ let Predicates = [HasExtXcvalu] in {
(CV_SUBRNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
def : Pat<(srl (add (sub GPR:$rd, GPR:$rs1), (roundBit GPR:$rs2)), GPR:$rs2),
(CV_SUBURNR GPR:$rd, GPR:$rs1, GPR:$rs2)>;

def : PatCoreVAluGpr<"abs", "ABS">;
def : PatCoreVAluGprGpr<"slet", "SLET">;
def : PatCoreVAluGprGpr<"sletu", "SLETU">;
def : PatCoreVAluGprGpr<"min", "MIN">;
def : PatCoreVAluGprGpr<"minu", "MINU">;
def : PatCoreVAluGprGpr<"max", "MAX">;
def : PatCoreVAluGprGpr<"maxu", "MAXU">;
def : PatCoreVAluGpr<"exths", "EXTHS">;
def : PatCoreVAluGpr<"exthz", "EXTHZ">;
def : PatCoreVAluGpr<"extbs", "EXTBS">;
def : PatCoreVAluGpr<"extbz", "EXTBZ">;

defm CLIP : PatCoreVAluGprImm<int_riscv_cv_alu_clip>;
defm CLIPU : PatCoreVAluGprImm<int_riscv_cv_alu_clipu>;
defm ADDN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addn>;
defm ADDUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addun>;
defm ADDRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addrn>;
defm ADDURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addurn>;
defm SUBN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subn>;
defm SUBUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subun>;
defm SUBRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subrn>;
defm SUBURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_suburn>;
}

//===----------------------------------------------------------------------===//
Expand Down
Loading

0 comments on commit 1442f85

Please sign in to comment.