Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4937,6 +4937,10 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
HelpText<"Disable using library calls for save and restore">;
} // let Flags = [TargetSpecific]
def mload_store_pairs : Flag<["-"], "mload-store-pairs">, Group<m_riscv_Features_Group>;
def mno_load_store_pairs : Flag<["-"], "mno-load-store-pairs">, Group<m_riscv_Features_Group>;
def mccmov : Flag<["-"], "mccmov">, Group<m_riscv_Features_Group>;
def mno_ccmov : Flag<["-"], "mno-ccmov">, Group<m_riscv_Features_Group>;
let Flags = [TargetSpecific] in {
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
HelpText<"Enable use of experimental RISC-V extensions.">;
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2164,6 +2164,20 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
CmdArgs.push_back(A->getValue());
}

if (Arg *A = Args.getLastArg(options::OPT_mload_store_pairs,
options::OPT_mno_load_store_pairs)) {
if (A->getOption().matches(options::OPT_mload_store_pairs)) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-riscv-load-store-pairs=1");
}
}

if (Arg *A = Args.getLastArg(options::OPT_mccmov, options::OPT_mno_ccmov)) {
if (A->getOption().matches(options::OPT_mno_ccmov)) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-riscv-ccmov=0");
}
}
// Handle -mrvv-vector-bits=<bits>
if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
StringRef Val = A->getValue();
Expand Down
2 changes: 2 additions & 0 deletions clang/test/Misc/target-invalid-cpu-note/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
// RISCV64: error: unknown target CPU 'not-a-cpu'
// RISCV64-NEXT: note: valid target CPU values are:
// RISCV64-SAME: {{^}} generic-rv64
// RISCV64-SAME: {{^}}, mips-p8700
// RISCV64-SAME: {{^}}, rocket-rv64
// RISCV64-SAME: {{^}}, sifive-p450
// RISCV64-SAME: {{^}}, sifive-p470
Expand Down Expand Up @@ -72,6 +73,7 @@
// TUNE-RISCV64: error: unknown target CPU 'not-a-cpu'
// TUNE-RISCV64-NEXT: note: valid target CPU values are:
// TUNE-RISCV64-SAME: {{^}} generic-rv64
// TUNE-RISCV64-SAME: {{^}}, mips-p8700
// TUNE-RISCV64-SAME: {{^}}, rocket-rv64
// TUNE-RISCV64-SAME: {{^}}, sifive-p450
// TUNE-RISCV64-SAME: {{^}}, sifive-p470
Expand Down
6 changes: 6 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,12 @@ The current vendor extensions supported are:
``Xwchc``
LLVM implements `the custom compressed opcodes present in some QingKe cores` by WCH / Nanjing Qinheng Microelectronics. The vendor refers to these opcodes by the name "XW".

``xmipscmove``
LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.

``xmipslsp``
LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.

Experimental C Intrinsics
=========================

Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_None;
}

bool isUImm7Lsb000() const {
if (!isImm())
return false;
int64_t Imm;
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
return IsConstantImm && isShiftedUInt<4, 3>(Imm) &&
VK == RISCVMCExpr::VK_RISCV_None;
}

bool isUImm8Lsb00() const {
if (!isImm())
return false;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ add_llvm_target(RISCVCodeGen
RISCVISelLowering.cpp
RISCVLandingPadSetup.cpp
RISCVMachineFunctionInfo.cpp
RISCVLoadStoreOptimizer.cpp
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
RISCVPostRAExpandPseudoInsts.cpp
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ enum OperandType : unsigned {
OPERAND_UIMM6_LSB0,
OPERAND_UIMM7,
OPERAND_UIMM7_LSB00,
OPERAND_UIMM7_LSB000,
OPERAND_UIMM8_LSB00,
OPERAND_UIMM8,
OPERAND_UIMM8_LSB000,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ void initializeRISCVMoveMergePass(PassRegistry &);

FunctionPass *createRISCVPushPopOptimizationPass();
void initializeRISCVPushPopOptPass(PassRegistry &);
FunctionPass *createRISCVLoadStoreOptPass();
void initializeRISCVLoadStoreOptPass(PassRegistry &);

FunctionPass *createRISCVZacasABIFixPass();
void initializeRISCVZacasABIFixPass(PassRegistry &);
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ include "RISCVMacroFusion.td"
// RISC-V Scheduling Models
//===----------------------------------------------------------------------===//

include "RISCVSchedMIPSP8700.td"
include "RISCVSchedRocket.td"
include "RISCVSchedSiFive7.td"
include "RISCVSchedSiFiveP400.td"
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,23 @@ def TuneConditionalCompressedMoveFusion
def HasConditionalMoveFusion : Predicate<"Subtarget->hasConditionalMoveFusion()">;
def NoConditionalMoveFusion : Predicate<"!Subtarget->hasConditionalMoveFusion()">;

def TuneMIPSP8700
: SubtargetFeature<"mips-p8700", "RISCVProcFamily", "Others",
"MIPS p8700 processor">;
def FeatureMIPSCMov : SubtargetFeature<"xmipscmov", "HasMIPSCMov",
"true", "Using CCMov",
[Feature64Bit]>;
def UsesMIPSCMov
: Predicate<"Subtarget->useCCMovInsn()">,
AssemblerPredicate<(all_of FeatureMIPSCMov), "'ccmov' instruction">;
def FeatureMIPSLoadStorePairs
: SubtargetFeature<"xmipslsp", "HasMIPSLSP", "true",
"Optimize for hardware load-store bonding">;
def UsesMIPSLoadStorePairs
: Predicate<"Subtarget->useLoadStorePairs()">,
AssemblerPredicate<(all_of FeatureMIPSLoadStorePairs),
"load and store pair instructions">;

def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7",
"SiFive 7-Series processors">;

Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ABS, MVT::i32, Custom);
}

if (!Subtarget.hasVendorXTHeadCondMov())
if (Subtarget.hasMIPSCMov())
setOperationAction(ISD::SELECT, XLenVT, Legal);
else if (!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);

static const unsigned FPLegalNodeTypes[] = {
Expand Down
72 changes: 72 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,78 @@ class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
let Inst{6-0} = opcode.Value;
}

//===----------------------------------------------------------------------===//
// MIPS custom instruction formats
//===----------------------------------------------------------------------===//

// Load double pair format.
class LDPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs1;
bits<5> rd1;
bits<5> rd2;

let Inst{31-27} = rd2;
let Inst{26-23} = imm7{6-3};
let Inst{22-20} = 0b000;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b100;
let Inst{11-7} = rd1;
let Inst{6-0} = 0b0001011;
}

// Load word pair format.
class LWPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs1;
bits<5> rd1;
bits<5> rd2;

let Inst{31-27} = rd2;
let Inst{26-22} = imm7{6-2};
let Inst{21-20} = 0b01;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b100;
let Inst{11-7} = rd1;
let Inst{6-0} = 0b0001011;
}

// Store double pair format.
class SDPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs3;
bits<5> rs2;
bits<5> rs1;

let Inst{31-27} = rs3;
let Inst{26-25} = imm7{6-5};
let Inst{24-20} = rs2;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b101;
let Inst{11-10} = imm7{4-3};
let Inst{9-0} = 0b0000001011;
}

// Store word pair format.
class SWPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs3;
bits<5> rs2;
bits<5> rs1;

let Inst{31-27} = rs3;
let Inst{26-25} = imm7{6-5};
let Inst{24-20} = rs2;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b101;
let Inst{11-9} = imm7{4-2};
let Inst{8-0} = 0b010001011;
}

//===----------------------------------------------------------------------===//
// Instruction classes for .insn directives
//===----------------------------------------------------------------------===//
Expand Down
42 changes: 42 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2464,6 +2464,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_UIMM7_LSB00:
Ok = isShiftedUInt<5, 2>(Imm);
break;
case RISCVOp::OPERAND_UIMM7_LSB000:
Ok = isShiftedUInt<4, 3>(Imm);
break;
case RISCVOp::OPERAND_UIMM8_LSB00:
Ok = isShiftedUInt<6, 2>(Imm);
break;
Expand Down Expand Up @@ -2710,6 +2713,45 @@ MachineInstr *RISCVInstrInfo::emitLdStWithAddr(MachineInstr &MemI,
.setMemRefs(MemI.memoperands())
.setMIFlags(MemI.getFlags());
}
bool RISCVInstrInfo::isPairableLdStInstOpc(unsigned Opc) {
switch (Opc) {
default:
return false;
case RISCV::SH:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This list doesn't match what's supported in RISCVLoadStoreOpt::tryConvertToLdStPair

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That is true. I have added a TODO marker for it in #121394.

case RISCV::LH:
case RISCV::LHU:
case RISCV::SW:
case RISCV::FSW:
case RISCV::LW:
case RISCV::FLW:
case RISCV::SD:
case RISCV::FSD:
case RISCV::LD:
case RISCV::FLD:
return true;
}
}

bool RISCVInstrInfo::isLdStSafeToPair(const MachineInstr &LdSt,
const TargetRegisterInfo *TRI) {
// If this is a volatile load/store, don't mess with it.
if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
return false;

if (LdSt.getOperand(1).isFI())
return true;

assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
// Can't cluster if the instruction modifies the base register
// or it is update form. e.g. ld x5,8(x5)
if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
return false;

if (!LdSt.getOperand(2).isImm())
return false;

return true;
}

bool RISCVInstrInfo::getMemOperandsWithOffsetWidth(
const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,15 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {

unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override;

/// Return true if pairing the given load or store may be paired with another.
static bool isPairableLdStInstOpc(unsigned Opc);

static bool isLdStSafeToPair(const MachineInstr &LdSt,
const TargetRegisterInfo *TRI);

std::optional<std::pair<unsigned, unsigned>>
isRVVSpillForZvlsseg(unsigned Opcode) const;

protected:
const RISCVSubtarget &STI;

Expand Down
Loading