summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp11
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfo.cpp2
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfo.td15
3 files changed, 18 insertions, 10 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 1d2a15c319b..535cee25a98 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1166,10 +1166,13 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
Glue = Chain.getValue(1);
}
- if (isa<GlobalAddressSDNode>(Callee)) {
- Callee = lowerGlobalAddress(Callee, DAG);
- } else if (isa<ExternalSymbolSDNode>(Callee)) {
- Callee = lowerExternalSymbol(Callee, DAG);
+ // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
+ // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
+ // split it and then direct call can be matched by PseudoCALL.
+ if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, 0);
+ } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, 0);
}
// The first call operand is the chain and the second is the target address.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 91a0dfb233f..2a567d8be8d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -387,6 +387,8 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
case TargetOpcode::KILL:
case TargetOpcode::DBG_VALUE:
return 0;
+ case RISCV::PseudoCALL:
+ return 8;
case TargetOpcode::INLINEASM: {
const MachineFunction &MF = *MI.getParent()->getParent();
const auto &TM = static_cast<const RISCVTargetMachine &>(MF.getTarget());
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 0309fe95000..4e528d1fc8e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -636,16 +636,19 @@ def : Pat<(brind (add GPR:$rs1, simm12:$imm12)),
(PseudoBRIND GPR:$rs1, simm12:$imm12)>;
// PseudoCALL is a pseudo instruction which will eventually expand to auipc
-// and jalr. Define AsmString because we want assembler could print "call"
-// when compile with -S. Define isCodeGenOnly = 0 because we want parser
-// could parsing assembly "call" instruction.
-let isCall = 1, Defs = [X1], isCodeGenOnly = 0,
- hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+// and jalr while encoding. This is desirable, as an auipc+jalr pair with
+// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker
+// if the offset fits in a signed 21-bit immediate.
+// Define AsmString to print "call" when compile with -S flag.
+// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
+let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in
def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func),
- []> {
+ [(Call tglobaladdr:$func)]> {
let AsmString = "call\t$func";
}
+def : Pat<(Call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
+
let isCall = 1, Defs = [X1] in
def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rs1), [(Call GPR:$rs1)]>,
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
OpenPOWER on IntegriCloud