[llvm] [RFC][RISCV] Support the large code model. (PR #70308)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 26 01:52:55 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Jim Lin (tclin914)
<details>
<summary>Changes</summary>
Implement large code model for GlobalAddressSDNode, BlockAddressSDNode and ExternalSymbolSDNode.
See discussion on
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/388.
co-authored by: Kuan-Lin Chen <rufus@<!-- -->andestech.com>
---
Patch is 95.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/70308.diff
10 Files Affected:
- (modified) llvm/lib/Target/RISCV/CMakeLists.txt (+1)
- (modified) llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp (+35)
- (added) llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp (+114)
- (added) llvm/lib/Target/RISCV/RISCVConstantPoolValue.h (+147)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+64-12)
- (modified) llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp (+1-1)
- (modified) llvm/test/CodeGen/RISCV/calls.ll (+524)
- (modified) llvm/test/CodeGen/RISCV/codemodel-lowering.ll (+161)
- (modified) llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll (+198)
- (modified) llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll (+553)
``````````diff
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 4d5fa79389ea68b..b6ed0b86e39e9ba 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -29,6 +29,7 @@ add_public_tablegen_target(RISCVCommonTableGen)
add_llvm_target(RISCVCodeGen
RISCVAsmPrinter.cpp
RISCVCodeGenPrepare.cpp
+ RISCVConstantPoolValue.cpp
RISCVDeadRegisterDefinitions.cpp
RISCVMakeCompressible.cpp
RISCVExpandAtomicPseudoInsts.cpp
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 0fd514fa87cd2f9..6308d1f574b4d03 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -16,6 +16,7 @@
#include "MCTargetDesc/RISCVMCExpr.h"
#include "MCTargetDesc/RISCVTargetStreamer.h"
#include "RISCV.h"
+#include "RISCVConstantPoolValue.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVTargetMachine.h"
#include "TargetInfo/RISCVTargetInfo.h"
@@ -75,6 +76,8 @@ class RISCVAsmPrinter : public AsmPrinter {
void emitInstruction(const MachineInstr *MI) override;
+ void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
+
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
const char *ExtraCode, raw_ostream &OS) override;
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
@@ -981,3 +984,35 @@ bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
}
return false;
}
+
+static MCSymbolRefExpr::VariantKind
+getModifierVariantKind(RISCVCP::RISCVCPModifier Modifier) {
+ switch (Modifier) {
+ case RISCVCP::None:
+ return MCSymbolRefExpr::VK_None;
+ }
+ llvm_unreachable("Invalid RISCVCPModifier!");
+}
+
+void RISCVAsmPrinter::emitMachineConstantPoolValue(
+ MachineConstantPoolValue *MCPV) {
+ auto *RCPV = static_cast<RISCVConstantPoolValue *>(MCPV);
+ MCSymbol *MCSym;
+
+ if (RCPV->isGlobalValue()) {
+ auto GV = cast<RISCVConstantPoolConstant>(RCPV)->getGlobalValue();
+ MCSym = getSymbol(GV);
+ } else if (RCPV->isBlockAddress()) {
+ auto BA = cast<RISCVConstantPoolConstant>(RCPV)->getBlockAddress();
+ MCSym = GetBlockAddressSymbol(BA);
+ } else {
+ assert(RCPV->isExtSymbol() && "unrecognized constant pool value");
+ auto Sym = cast<RISCVConstantPoolSymbol>(RCPV)->getSymbol();
+ MCSym = GetExternalSymbolSymbol(Sym);
+ }
+
+ const MCExpr *Expr = MCSymbolRefExpr::create(
+ MCSym, getModifierVariantKind(RCPV->getModifier()), OutContext);
+ uint64_t Size = getDataLayout().getTypeAllocSize(RCPV->getType());
+ OutStreamer->emitValue(Expr, Size);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
new file mode 100644
index 000000000000000..398dfbd9bb65948
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
@@ -0,0 +1,114 @@
+//===------- RISCVConstantPoolValue.cpp - RISC-V constantpool value -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the RISC-V specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVConstantPoolValue.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+RISCVConstantPoolValue::RISCVConstantPoolValue(
+ LLVMContext &C, RISCVCP::RISCVCPKind Kind,
+ RISCVCP::RISCVCPModifier Modifier)
+ : MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind),
+ Modifier(Modifier) {}
+
+RISCVConstantPoolValue::RISCVConstantPoolValue(
+ Type *Ty, RISCVCP::RISCVCPKind Kind, RISCVCP::RISCVCPModifier Modifier)
+ : MachineConstantPoolValue(Ty), Kind(Kind), Modifier(Modifier) {}
+
+int RISCVConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) {
+ llvm_unreachable("Shouldn't be calling this directly!");
+}
+
+StringRef RISCVConstantPoolValue::getModifierText() const {
+ switch (Modifier) {
+ case RISCVCP::None:
+ return "";
+ }
+ llvm_unreachable("Unknown modifier!");
+}
+
+void RISCVConstantPoolValue::print(raw_ostream &O) const {
+ if (hasModifier())
+ O << "@" << getModifierText();
+}
+
+RISCVConstantPoolConstant::RISCVConstantPoolConstant(Type *Ty,
+ const Constant *GV,
+ RISCVCP::RISCVCPKind Kind)
+ : RISCVConstantPoolValue(Ty, Kind, RISCVCP::None), CVal(GV) {}
+
+RISCVConstantPoolConstant *
+RISCVConstantPoolConstant::Create(const GlobalValue *GV,
+ RISCVCP::RISCVCPKind Kind) {
+ return new RISCVConstantPoolConstant(GV->getType(), GV, Kind);
+}
+
+RISCVConstantPoolConstant *
+RISCVConstantPoolConstant::Create(const Constant *C,
+ RISCVCP::RISCVCPKind Kind) {
+ return new RISCVConstantPoolConstant(C->getType(), C, Kind);
+}
+
+int RISCVConstantPoolConstant::getExistingMachineCPValue(
+ MachineConstantPool *CP, Align Alignment) {
+ return getExistingMachineCPValueImpl<RISCVConstantPoolConstant>(CP,
+ Alignment);
+}
+
+void RISCVConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
+ ID.AddPointer(CVal);
+}
+
+void RISCVConstantPoolConstant::print(raw_ostream &O) const {
+ O << CVal->getName();
+ RISCVConstantPoolValue::print(O);
+}
+
+const GlobalValue *RISCVConstantPoolConstant::getGlobalValue() const {
+ return dyn_cast_or_null<GlobalValue>(CVal);
+}
+
+const BlockAddress *RISCVConstantPoolConstant::getBlockAddress() const {
+ return dyn_cast_or_null<BlockAddress>(CVal);
+}
+
+RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(
+ LLVMContext &C, StringRef s, RISCVCP::RISCVCPModifier Modifier)
+ : RISCVConstantPoolValue(C, RISCVCP::ExtSymbol, Modifier), S(s) {}
+
+RISCVConstantPoolSymbol *
+RISCVConstantPoolSymbol::Create(LLVMContext &C, StringRef s,
+ RISCVCP::RISCVCPModifier Modifier) {
+ return new RISCVConstantPoolSymbol(C, s, Modifier);
+}
+
+int RISCVConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) {
+ return getExistingMachineCPValueImpl<RISCVConstantPoolSymbol>(CP, Alignment);
+}
+
+void RISCVConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
+ ID.AddString(S);
+}
+
+void RISCVConstantPoolSymbol::print(raw_ostream &O) const {
+ O << S;
+ RISCVConstantPoolValue::print(O);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
new file mode 100644
index 000000000000000..8edd95e9a065fd7
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -0,0 +1,147 @@
+//===--- RISCVConstantPoolValue.h - RISC-V constantpool value ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the RISC-V specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
+#define LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
+
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class LLVMContext;
+class GlobalValue;
+class BlockAddress;
+
+namespace RISCVCP {
+
+enum RISCVCPKind { ExtSymbol, GlobalValue, BlockAddress };
+
+enum RISCVCPModifier {
+ None,
+};
+} // end namespace RISCVCP
+
+/// A RISCV-specific constant pool value.
+class RISCVConstantPoolValue : public MachineConstantPoolValue {
+ RISCVCP::RISCVCPKind Kind;
+ RISCVCP::RISCVCPModifier Modifier;
+
+protected:
+ RISCVConstantPoolValue(LLVMContext &C, RISCVCP::RISCVCPKind Kind,
+ RISCVCP::RISCVCPModifier Modifier);
+
+ RISCVConstantPoolValue(Type *Ty, RISCVCP::RISCVCPKind Kind,
+ RISCVCP::RISCVCPModifier Modifier);
+
+ template <typename Derived>
+ int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
+ const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
+ for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
+ if (Constants[i].isMachineConstantPoolEntry() &&
+ Constants[i].getAlign() >= Alignment) {
+ auto *CPV = static_cast<RISCVConstantPoolValue *>(
+ Constants[i].Val.MachineCPVal);
+ if (Derived *APC = dyn_cast<Derived>(CPV))
+ if (cast<Derived>(this)->equals(APC))
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+public:
+ ~RISCVConstantPoolValue() = default;
+
+ RISCVCP::RISCVCPModifier getModifier() const { return Modifier; }
+ StringRef getModifierText() const;
+ bool hasModifier() const { return Modifier != RISCVCP::None; }
+
+ bool isExtSymbol() const { return Kind == RISCVCP::ExtSymbol; }
+ bool isGlobalValue() const { return Kind == RISCVCP::GlobalValue; }
+ bool isBlockAddress() const { return Kind == RISCVCP::BlockAddress; }
+
+ int getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) override;
+
+ void addSelectionDAGCSEId(FoldingSetNodeID &ID) override {}
+
+ bool equals(const RISCVConstantPoolValue *A) const {
+ return this->Modifier == A->Modifier;
+ }
+
+ void print(raw_ostream &O) const override;
+};
+
+class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
+ const Constant *CVal;
+
+ RISCVConstantPoolConstant(Type *Ty, const Constant *GV,
+ RISCVCP::RISCVCPKind Kind);
+
+public:
+ static RISCVConstantPoolConstant *Create(const GlobalValue *GV,
+ RISCVCP::RISCVCPKind Kind);
+ static RISCVConstantPoolConstant *Create(const Constant *C,
+ RISCVCP::RISCVCPKind Kind);
+
+ const GlobalValue *getGlobalValue() const;
+ const BlockAddress *getBlockAddress() const;
+
+ int getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) override;
+
+ void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
+
+ void print(raw_ostream &O) const override;
+
+ bool equals(const RISCVConstantPoolConstant *A) const {
+ return CVal == A->CVal && RISCVConstantPoolValue::equals(A);
+ }
+
+ static bool classof(const RISCVConstantPoolValue *RCPV) {
+ return RCPV->isGlobalValue() || RCPV->isBlockAddress();
+ }
+};
+
+class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
+ const std::string S;
+
+ RISCVConstantPoolSymbol(LLVMContext &C, StringRef s,
+ RISCVCP::RISCVCPModifier Modifier);
+
+public:
+ static RISCVConstantPoolSymbol *Create(LLVMContext &C, StringRef s,
+ RISCVCP ::RISCVCPModifier Modifier);
+
+ std::string getSymbol() const { return S; }
+
+ int getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) override;
+
+ void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
+
+ void print(raw_ostream &O) const override;
+
+ bool equals(const RISCVConstantPoolSymbol *A) const {
+ return S == A->S && RISCVConstantPoolValue::equals(A);
+ }
+ static bool classof(const RISCVConstantPoolValue *RCPV) {
+ return RCPV->isExtSymbol();
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index beb371063f89b2d..e523995a909f599 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -14,6 +14,7 @@
#include "RISCVISelLowering.h"
#include "MCTargetDesc/RISCVMatInt.h"
#include "RISCV.h"
+#include "RISCVConstantPoolValue.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVRegisterInfo.h"
#include "RISCVSubtarget.h"
@@ -6431,6 +6432,44 @@ static SDValue getTargetNode(JumpTableSDNode *N, const SDLoc &DL, EVT Ty,
return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
}
+static SDValue getTargetNode(ExternalSymbolSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG, unsigned Flags) {
+ llvm_unreachable("Unexpected node type.");
+}
+
+template <class NodeTy>
+static SDValue getLargeAddr(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG) {
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N)) {
+ RISCVConstantPoolConstant *CPV =
+ RISCVConstantPoolConstant::Create(G->getGlobal(), RISCVCP::GlobalValue);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
+ SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
+ return DAG.getLoad(
+ Ty, DL, DAG.getEntryNode(), LC,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
+ } else if (BlockAddressSDNode *B = dyn_cast<BlockAddressSDNode>(N)) {
+ RISCVConstantPoolConstant *CPV = RISCVConstantPoolConstant::Create(
+ B->getBlockAddress(), RISCVCP::BlockAddress);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
+ SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
+ return DAG.getLoad(
+ Ty, DL, DAG.getEntryNode(), LC,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
+ } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N)) {
+ RISCVConstantPoolSymbol *CPV = RISCVConstantPoolSymbol::Create(
+ *DAG.getContext(), S->getSymbol(), RISCVCP::None);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
+ SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
+ return DAG.getLoad(
+ Ty, DL, DAG.getEntryNode(), LC,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
+ } else {
+ // Using pc-relative mode for other node type.
+ SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
+ return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr);
+ }
+}
+
template <class NodeTy>
SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
bool IsLocal, bool IsExternWeak) const {
@@ -6499,6 +6538,9 @@ SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
// expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr);
}
+ case CodeModel::Large: {
+ return getLargeAddr(N, DL, Ty, DAG);
+ }
}
}
@@ -17489,22 +17531,32 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// 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)) {
- const GlobalValue *GV = S->getGlobal();
+ if (getTargetMachine().getCodeModel() == CodeModel::Large) {
+ if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ Callee = getLargeAddr(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
+ } else if (ExternalSymbolSDNode *S =
+ dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ Callee = getLargeAddr(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
+ }
+ } else {
+ if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ const GlobalValue *GV = S->getGlobal();
+ unsigned OpFlags = RISCVII::MO_CALL;
- unsigned OpFlags = RISCVII::MO_CALL;
- if (!getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))
- OpFlags = RISCVII::MO_PLT;
+ if (!getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))
+ OpFlags = RISCVII::MO_PLT;
- Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
- } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
- unsigned OpFlags = RISCVII::MO_CALL;
+ Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
+ } else if (ExternalSymbolSDNode *S =
+ dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ unsigned OpFlags = RISCVII::MO_CALL;
- if (!getTargetMachine().shouldAssumeDSOLocal(*MF.getFunction().getParent(),
- nullptr))
- OpFlags = RISCVII::MO_PLT;
+ if (!getTargetMachine().shouldAssumeDSOLocal(
+ *MF.getFunction().getParent(), nullptr))
+ OpFlags = RISCVII::MO_PLT;
- Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags);
+ Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags);
+ }
}
// The first call operand is the chain and the second is the target address.
diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
index 7c9e57e6eef3ced..ea9ab37ae415ce6 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
@@ -114,7 +114,7 @@ bool RISCVELFTargetObjectFile::isConstantInSmallSection(
MCSection *RISCVELFTargetObjectFile::getSectionForConstant(
const DataLayout &DL, SectionKind Kind, const Constant *C,
Align &Alignment) const {
- if (isConstantInSmallSection(DL, C))
+ if (C && isConstantInSmallSection(DL, C))
return SmallDataSection;
// Otherwise, we work the same as ELF.
diff --git a/llvm/test/CodeGen/RISCV/calls.ll b/llvm/test/CodeGen/RISCV/calls.ll
index e3459875362d45d..509daaa2970cd20 100644
--- a/llvm/test/CodeGen/RISCV/calls.ll
+++ b/llvm/test/CodeGen/RISCV/calls.ll
@@ -3,6 +3,14 @@
; RUN: | FileCheck -check-prefix=RV32I %s
; RUN: llc -relocation-model=pic -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I-PIC %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
+; RUN: llc -code-model=small -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I-SMALL %s
+; RUN: llc -code-model=medium -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I-MEDIUM %s
+; RUN: llc -code-model=large -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I-LARGE %s
declare i32 @external_function(i32)
@@ -24,6 +32,45 @@ define i32 @test_call_external(i32 %a) nounwind {
; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-PIC-NEXT: addi sp, sp, 16
; RV32I-PIC-NEXT: ret
+;
+; RV64I-LABEL: test_call_external:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: call external_function at plt
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_external:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: addi sp, sp, -16
+; RV64I-SMALL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-SMALL-NEXT: call external_function at plt
+; RV64I-SMALL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-SMALL-NEXT: addi sp, sp, 16
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: test_call_external:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: addi sp, sp, -16
+; RV64I-MEDIUM-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-MEDIUM-NEXT: call external_function at plt
+; RV64I-MEDIUM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-MEDIUM-NEXT: addi sp, sp, 16
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: test_call_external:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: addi sp, sp, -16
+; RV64I-LARGE-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: .Lp...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/70308
More information about the llvm-commits
mailing list