[llvm] [RFC][RISCV] Support the large code model. (PR #70308)
Jim Lin via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 20 23:52:01 PST 2023
https://github.com/tclin914 updated https://github.com/llvm/llvm-project/pull/70308
>From 5cd0e500f7ba7490bf3b854f2a2c9299bd131d9d Mon Sep 17 00:00:00 2001
From: Kuan-Lin Chen <rufus at andestech.com>
Date: Thu, 17 Sep 2020 17:09:13 +0800
Subject: [PATCH 1/7] [RFC][RISCV] Support the large code model.
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 at andestech.com>
---
llvm/lib/Target/RISCV/CMakeLists.txt | 1 +
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 35 ++
.../Target/RISCV/RISCVConstantPoolValue.cpp | 114 ++++
.../lib/Target/RISCV/RISCVConstantPoolValue.h | 147 +++++
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 76 ++-
.../Target/RISCV/RISCVTargetObjectFile.cpp | 2 +-
llvm/test/CodeGen/RISCV/calls.ll | 524 +++++++++++++++++
llvm/test/CodeGen/RISCV/codemodel-lowering.ll | 161 +++++
.../test/CodeGen/RISCV/fold-addi-loadstore.ll | 198 +++++++
.../RISCV/inline-asm-mem-constraint.ll | 553 ++++++++++++++++++
10 files changed, 1798 insertions(+), 13 deletions(-)
create mode 100644 llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
create mode 100644 llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 4d5fa79389ea68..b6ed0b86e39e9b 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 0fd514fa87cd2f..6308d1f574b4d0 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 00000000000000..398dfbd9bb6594
--- /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 00000000000000..8edd95e9a065fd
--- /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 beb371063f89b2..e523995a909f59 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 7c9e57e6eef3ce..ea9ab37ae415ce 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 e3459875362d45..509daaa2970cd2 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: .Lpcrel_hi0:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI0_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi0)(a1)
+; RV64I-LARGE-NEXT: jalr a1
+; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
%1 = call i32 @external_function(i32 %a)
ret i32 %1
}
@@ -48,6 +95,45 @@ define i32 @test_call_dso_local(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_dso_local:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: call dso_local_function
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_dso_local:
+; 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 dso_local_function
+; 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_dso_local:
+; 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 dso_local_function
+; 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_dso_local:
+; 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: .Lpcrel_hi1:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI1_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi1)(a1)
+; RV64I-LARGE-NEXT: jalr a1
+; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
%1 = call i32 @dso_local_function(i32 %a)
ret i32 %1
}
@@ -62,6 +148,26 @@ define i32 @defined_function(i32 %a) nounwind {
; RV32I-PIC: # %bb.0:
; RV32I-PIC-NEXT: addi a0, a0, 1
; RV32I-PIC-NEXT: ret
+;
+; RV64I-LABEL: defined_function:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addiw a0, a0, 1
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: defined_function:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: addiw a0, a0, 1
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: defined_function:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: addiw a0, a0, 1
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: defined_function:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: addiw a0, a0, 1
+; RV64I-LARGE-NEXT: ret
%1 = add i32 %a, 1
ret i32 %1
}
@@ -84,6 +190,45 @@ define i32 @test_call_defined(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_defined:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: call defined_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_defined:
+; 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 defined_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_defined:
+; 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 defined_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_defined:
+; 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: .Lpcrel_hi2:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI3_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi2)(a1)
+; RV64I-LARGE-NEXT: jalr a1
+; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
%1 = call i32 @defined_function(i32 %a)
ret i32 %1
}
@@ -110,6 +255,50 @@ define i32 @test_call_indirect(ptr %a, i32 %b) 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_indirect:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: mv a2, a0
+; RV64I-NEXT: mv a0, a1
+; RV64I-NEXT: jalr a2
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_indirect:
+; 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: mv a2, a0
+; RV64I-SMALL-NEXT: mv a0, a1
+; RV64I-SMALL-NEXT: jalr a2
+; 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_indirect:
+; 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: mv a2, a0
+; RV64I-MEDIUM-NEXT: mv a0, a1
+; RV64I-MEDIUM-NEXT: jalr a2
+; 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_indirect:
+; 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: mv a2, a0
+; RV64I-LARGE-NEXT: mv a0, a1
+; RV64I-LARGE-NEXT: jalr a2
+; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
%1 = call i32 %a(i32 %b)
ret i32 %1
}
@@ -150,6 +339,74 @@ define i32 @test_call_indirect_no_t0(ptr %a, i32 %b, i32 %c, i32 %d, i32 %e, i32
; 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_indirect_no_t0:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: mv t1, a0
+; RV64I-NEXT: mv a0, a1
+; RV64I-NEXT: mv a1, a2
+; RV64I-NEXT: mv a2, a3
+; RV64I-NEXT: mv a3, a4
+; RV64I-NEXT: mv a4, a5
+; RV64I-NEXT: mv a5, a6
+; RV64I-NEXT: mv a6, a7
+; RV64I-NEXT: jalr t1
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_indirect_no_t0:
+; 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: mv t1, a0
+; RV64I-SMALL-NEXT: mv a0, a1
+; RV64I-SMALL-NEXT: mv a1, a2
+; RV64I-SMALL-NEXT: mv a2, a3
+; RV64I-SMALL-NEXT: mv a3, a4
+; RV64I-SMALL-NEXT: mv a4, a5
+; RV64I-SMALL-NEXT: mv a5, a6
+; RV64I-SMALL-NEXT: mv a6, a7
+; RV64I-SMALL-NEXT: jalr t1
+; 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_indirect_no_t0:
+; 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: mv t1, a0
+; RV64I-MEDIUM-NEXT: mv a0, a1
+; RV64I-MEDIUM-NEXT: mv a1, a2
+; RV64I-MEDIUM-NEXT: mv a2, a3
+; RV64I-MEDIUM-NEXT: mv a3, a4
+; RV64I-MEDIUM-NEXT: mv a4, a5
+; RV64I-MEDIUM-NEXT: mv a5, a6
+; RV64I-MEDIUM-NEXT: mv a6, a7
+; RV64I-MEDIUM-NEXT: jalr t1
+; 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_indirect_no_t0:
+; 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: mv t1, a0
+; RV64I-LARGE-NEXT: mv a0, a1
+; RV64I-LARGE-NEXT: mv a1, a2
+; RV64I-LARGE-NEXT: mv a2, a3
+; RV64I-LARGE-NEXT: mv a3, a4
+; RV64I-LARGE-NEXT: mv a4, a5
+; RV64I-LARGE-NEXT: mv a5, a6
+; RV64I-LARGE-NEXT: mv a6, a7
+; RV64I-LARGE-NEXT: jalr t1
+; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
%1 = call i32 %a(i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h)
ret i32 %1
}
@@ -167,6 +424,26 @@ define fastcc i32 @fastcc_function(i32 %a, i32 %b) nounwind {
; RV32I-PIC: # %bb.0:
; RV32I-PIC-NEXT: add a0, a0, a1
; RV32I-PIC-NEXT: ret
+;
+; RV64I-LABEL: fastcc_function:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addw a0, a0, a1
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: fastcc_function:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: addw a0, a0, a1
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: fastcc_function:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: addw a0, a0, a1
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: fastcc_function:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: addw a0, a0, a1
+; RV64I-LARGE-NEXT: ret
%1 = add i32 %a, %b
ret i32 %1
}
@@ -197,6 +474,62 @@ define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind {
; RV32I-PIC-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-PIC-NEXT: addi sp, sp, 16
; RV32I-PIC-NEXT: ret
+;
+; RV64I-LABEL: test_call_fastcc:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64I-NEXT: mv s0, a0
+; RV64I-NEXT: call fastcc_function at plt
+; RV64I-NEXT: mv a0, s0
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_fastcc:
+; 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: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64I-SMALL-NEXT: mv s0, a0
+; RV64I-SMALL-NEXT: call fastcc_function at plt
+; RV64I-SMALL-NEXT: mv a0, s0
+; RV64I-SMALL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-SMALL-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64I-SMALL-NEXT: addi sp, sp, 16
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: test_call_fastcc:
+; 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: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64I-MEDIUM-NEXT: mv s0, a0
+; RV64I-MEDIUM-NEXT: call fastcc_function at plt
+; RV64I-MEDIUM-NEXT: mv a0, s0
+; RV64I-MEDIUM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-MEDIUM-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64I-MEDIUM-NEXT: addi sp, sp, 16
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: test_call_fastcc:
+; 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: sd s0, 0(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: mv s0, a0
+; RV64I-LARGE-NEXT: .Lpcrel_hi3:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI7_0)
+; RV64I-LARGE-NEXT: ld a2, %pcrel_lo(.Lpcrel_hi3)(a0)
+; RV64I-LARGE-NEXT: mv a0, s0
+; RV64I-LARGE-NEXT: jalr a2
+; RV64I-LARGE-NEXT: mv a0, s0
+; RV64I-LARGE-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
%1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
ret i32 %a
}
@@ -247,6 +580,98 @@ define i32 @test_call_external_many_args(i32 %a) nounwind {
; RV32I-PIC-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-PIC-NEXT: addi sp, sp, 16
; RV32I-PIC-NEXT: ret
+;
+; RV64I-LABEL: test_call_external_many_args:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -32
+; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64I-NEXT: mv s0, a0
+; RV64I-NEXT: sd a0, 8(sp)
+; RV64I-NEXT: sd a0, 0(sp)
+; RV64I-NEXT: mv a1, a0
+; RV64I-NEXT: mv a2, a0
+; RV64I-NEXT: mv a3, a0
+; RV64I-NEXT: mv a4, a0
+; RV64I-NEXT: mv a5, a0
+; RV64I-NEXT: mv a6, a0
+; RV64I-NEXT: mv a7, a0
+; RV64I-NEXT: call external_many_args at plt
+; RV64I-NEXT: mv a0, s0
+; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 32
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_external_many_args:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: addi sp, sp, -32
+; RV64I-SMALL-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-SMALL-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64I-SMALL-NEXT: mv s0, a0
+; RV64I-SMALL-NEXT: sd a0, 8(sp)
+; RV64I-SMALL-NEXT: sd a0, 0(sp)
+; RV64I-SMALL-NEXT: mv a1, a0
+; RV64I-SMALL-NEXT: mv a2, a0
+; RV64I-SMALL-NEXT: mv a3, a0
+; RV64I-SMALL-NEXT: mv a4, a0
+; RV64I-SMALL-NEXT: mv a5, a0
+; RV64I-SMALL-NEXT: mv a6, a0
+; RV64I-SMALL-NEXT: mv a7, a0
+; RV64I-SMALL-NEXT: call external_many_args at plt
+; RV64I-SMALL-NEXT: mv a0, s0
+; RV64I-SMALL-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-SMALL-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64I-SMALL-NEXT: addi sp, sp, 32
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: test_call_external_many_args:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: addi sp, sp, -32
+; RV64I-MEDIUM-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-MEDIUM-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64I-MEDIUM-NEXT: mv s0, a0
+; RV64I-MEDIUM-NEXT: sd a0, 8(sp)
+; RV64I-MEDIUM-NEXT: sd a0, 0(sp)
+; RV64I-MEDIUM-NEXT: mv a1, a0
+; RV64I-MEDIUM-NEXT: mv a2, a0
+; RV64I-MEDIUM-NEXT: mv a3, a0
+; RV64I-MEDIUM-NEXT: mv a4, a0
+; RV64I-MEDIUM-NEXT: mv a5, a0
+; RV64I-MEDIUM-NEXT: mv a6, a0
+; RV64I-MEDIUM-NEXT: mv a7, a0
+; RV64I-MEDIUM-NEXT: call external_many_args at plt
+; RV64I-MEDIUM-NEXT: mv a0, s0
+; RV64I-MEDIUM-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-MEDIUM-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64I-MEDIUM-NEXT: addi sp, sp, 32
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: test_call_external_many_args:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: addi sp, sp, -32
+; RV64I-LARGE-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: mv s0, a0
+; RV64I-LARGE-NEXT: .Lpcrel_hi4:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI8_0)
+; RV64I-LARGE-NEXT: ld t1, %pcrel_lo(.Lpcrel_hi4)(a0)
+; RV64I-LARGE-NEXT: sd s0, 8(sp)
+; RV64I-LARGE-NEXT: sd s0, 0(sp)
+; RV64I-LARGE-NEXT: mv a0, s0
+; RV64I-LARGE-NEXT: mv a1, s0
+; RV64I-LARGE-NEXT: mv a2, s0
+; RV64I-LARGE-NEXT: mv a3, s0
+; RV64I-LARGE-NEXT: mv a4, s0
+; RV64I-LARGE-NEXT: mv a5, s0
+; RV64I-LARGE-NEXT: mv a6, s0
+; RV64I-LARGE-NEXT: mv a7, s0
+; RV64I-LARGE-NEXT: jalr t1
+; RV64I-LARGE-NEXT: mv a0, s0
+; RV64I-LARGE-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 32
+; RV64I-LARGE-NEXT: ret
%1 = call i32 @external_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
ret i32 %a
@@ -264,6 +689,30 @@ define i32 @defined_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 %
; RV32I-PIC-NEXT: lw a0, 4(sp)
; RV32I-PIC-NEXT: addi a0, a0, 1
; RV32I-PIC-NEXT: ret
+;
+; RV64I-LABEL: defined_many_args:
+; RV64I: # %bb.0:
+; RV64I-NEXT: lw a0, 8(sp)
+; RV64I-NEXT: addiw a0, a0, 1
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: defined_many_args:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: lw a0, 8(sp)
+; RV64I-SMALL-NEXT: addiw a0, a0, 1
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: defined_many_args:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: lw a0, 8(sp)
+; RV64I-MEDIUM-NEXT: addiw a0, a0, 1
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: defined_many_args:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: lw a0, 8(sp)
+; RV64I-LARGE-NEXT: addiw a0, a0, 1
+; RV64I-LARGE-NEXT: ret
%added = add i32 %j, 1
ret i32 %added
}
@@ -304,6 +753,81 @@ define i32 @test_call_defined_many_args(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_defined_many_args:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -32
+; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-NEXT: sd a0, 8(sp)
+; RV64I-NEXT: sd a0, 0(sp)
+; RV64I-NEXT: mv a1, a0
+; RV64I-NEXT: mv a2, a0
+; RV64I-NEXT: mv a3, a0
+; RV64I-NEXT: mv a4, a0
+; RV64I-NEXT: mv a5, a0
+; RV64I-NEXT: mv a6, a0
+; RV64I-NEXT: mv a7, a0
+; RV64I-NEXT: call defined_many_args at plt
+; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 32
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_defined_many_args:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: addi sp, sp, -32
+; RV64I-SMALL-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-SMALL-NEXT: sd a0, 8(sp)
+; RV64I-SMALL-NEXT: sd a0, 0(sp)
+; RV64I-SMALL-NEXT: mv a1, a0
+; RV64I-SMALL-NEXT: mv a2, a0
+; RV64I-SMALL-NEXT: mv a3, a0
+; RV64I-SMALL-NEXT: mv a4, a0
+; RV64I-SMALL-NEXT: mv a5, a0
+; RV64I-SMALL-NEXT: mv a6, a0
+; RV64I-SMALL-NEXT: mv a7, a0
+; RV64I-SMALL-NEXT: call defined_many_args at plt
+; RV64I-SMALL-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-SMALL-NEXT: addi sp, sp, 32
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: test_call_defined_many_args:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: addi sp, sp, -32
+; RV64I-MEDIUM-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-MEDIUM-NEXT: sd a0, 8(sp)
+; RV64I-MEDIUM-NEXT: sd a0, 0(sp)
+; RV64I-MEDIUM-NEXT: mv a1, a0
+; RV64I-MEDIUM-NEXT: mv a2, a0
+; RV64I-MEDIUM-NEXT: mv a3, a0
+; RV64I-MEDIUM-NEXT: mv a4, a0
+; RV64I-MEDIUM-NEXT: mv a5, a0
+; RV64I-MEDIUM-NEXT: mv a6, a0
+; RV64I-MEDIUM-NEXT: mv a7, a0
+; RV64I-MEDIUM-NEXT: call defined_many_args at plt
+; RV64I-MEDIUM-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-MEDIUM-NEXT: addi sp, sp, 32
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: test_call_defined_many_args:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: addi sp, sp, -32
+; RV64I-LARGE-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: .Lpcrel_hi5:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI10_0)
+; RV64I-LARGE-NEXT: ld t1, %pcrel_lo(.Lpcrel_hi5)(a1)
+; RV64I-LARGE-NEXT: sd a0, 8(sp)
+; RV64I-LARGE-NEXT: sd a0, 0(sp)
+; RV64I-LARGE-NEXT: mv a1, a0
+; RV64I-LARGE-NEXT: mv a2, a0
+; RV64I-LARGE-NEXT: mv a3, a0
+; RV64I-LARGE-NEXT: mv a4, a0
+; RV64I-LARGE-NEXT: mv a5, a0
+; RV64I-LARGE-NEXT: mv a6, a0
+; RV64I-LARGE-NEXT: mv a7, a0
+; RV64I-LARGE-NEXT: jalr t1
+; RV64I-LARGE-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 32
+; RV64I-LARGE-NEXT: ret
%1 = call i32 @defined_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
ret i32 %1
diff --git a/llvm/test/CodeGen/RISCV/codemodel-lowering.ll b/llvm/test/CodeGen/RISCV/codemodel-lowering.ll
index 617155b3197618..4c8d8f772b60a3 100644
--- a/llvm/test/CodeGen/RISCV/codemodel-lowering.ll
+++ b/llvm/test/CodeGen/RISCV/codemodel-lowering.ll
@@ -3,6 +3,12 @@
; RUN: | FileCheck %s -check-prefix=RV32I-SMALL
; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi=ilp32f -code-model=medium -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV32I-MEDIUM
+; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi=lp64f -code-model=small -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV64I-SMALL
+; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi=lp64f -code-model=medium -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV64I-MEDIUM
+; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi=lp64f -code-model=large -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV64I-LARGE
; Check lowering of globals
@G = global i32 0
@@ -20,6 +26,27 @@ define i32 @lower_global(i32 %a) nounwind {
; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(G)
; RV32I-MEDIUM-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi0)(a0)
; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-SMALL-LABEL: lower_global:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: lui a0, %hi(G)
+; RV64I-SMALL-NEXT: lw a0, %lo(G)(a0)
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: lower_global:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi0:
+; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(G)
+; RV64I-MEDIUM-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: lower_global:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi0:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI0_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV64I-LARGE-NEXT: lw a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
%1 = load volatile i32, ptr @G
ret i32 %1
}
@@ -43,6 +70,30 @@ define void @lower_blockaddress() nounwind {
; RV32I-MEDIUM-NEXT: li a1, 1
; RV32I-MEDIUM-NEXT: sw a1, %pcrel_lo(.Lpcrel_hi1)(a0)
; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-SMALL-LABEL: lower_blockaddress:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: lui a0, %hi(addr)
+; RV64I-SMALL-NEXT: li a1, 1
+; RV64I-SMALL-NEXT: sd a1, %lo(addr)(a0)
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: lower_blockaddress:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi1:
+; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(addr)
+; RV64I-MEDIUM-NEXT: li a1, 1
+; RV64I-MEDIUM-NEXT: sd a1, %pcrel_lo(.Lpcrel_hi1)(a0)
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: lower_blockaddress:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi1:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI1_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
+; RV64I-LARGE-NEXT: li a1, 1
+; RV64I-LARGE-NEXT: sd a1, 0(a0)
+; RV64I-LARGE-NEXT: ret
store volatile ptr blockaddress(@lower_blockaddress, %block), ptr @addr
ret void
@@ -95,6 +146,71 @@ define signext i32 @lower_blockaddress_displ(i32 signext %w) nounwind {
; RV32I-MEDIUM-NEXT: li a0, 3
; RV32I-MEDIUM-NEXT: addi sp, sp, 16
; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-SMALL-LABEL: lower_blockaddress_displ:
+; RV64I-SMALL: # %bb.0: # %entry
+; RV64I-SMALL-NEXT: addi sp, sp, -16
+; RV64I-SMALL-NEXT: lui a1, %hi(.Ltmp0)
+; RV64I-SMALL-NEXT: addi a1, a1, %lo(.Ltmp0)
+; RV64I-SMALL-NEXT: li a2, 101
+; RV64I-SMALL-NEXT: sd a1, 8(sp)
+; RV64I-SMALL-NEXT: blt a0, a2, .LBB2_3
+; RV64I-SMALL-NEXT: # %bb.1: # %if.then
+; RV64I-SMALL-NEXT: ld a0, 8(sp)
+; RV64I-SMALL-NEXT: jr a0
+; RV64I-SMALL-NEXT: .Ltmp0: # Block address taken
+; RV64I-SMALL-NEXT: .LBB2_2: # %return
+; RV64I-SMALL-NEXT: li a0, 4
+; RV64I-SMALL-NEXT: addi sp, sp, 16
+; RV64I-SMALL-NEXT: ret
+; RV64I-SMALL-NEXT: .LBB2_3: # %return.clone
+; RV64I-SMALL-NEXT: li a0, 3
+; RV64I-SMALL-NEXT: addi sp, sp, 16
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: lower_blockaddress_displ:
+; RV64I-MEDIUM: # %bb.0: # %entry
+; RV64I-MEDIUM-NEXT: addi sp, sp, -16
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi2:
+; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(.Ltmp0)
+; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi2)
+; RV64I-MEDIUM-NEXT: li a2, 101
+; RV64I-MEDIUM-NEXT: sd a1, 8(sp)
+; RV64I-MEDIUM-NEXT: blt a0, a2, .LBB2_3
+; RV64I-MEDIUM-NEXT: # %bb.1: # %if.then
+; RV64I-MEDIUM-NEXT: ld a0, 8(sp)
+; RV64I-MEDIUM-NEXT: jr a0
+; RV64I-MEDIUM-NEXT: .Ltmp0: # Block address taken
+; RV64I-MEDIUM-NEXT: .LBB2_2: # %return
+; RV64I-MEDIUM-NEXT: li a0, 4
+; RV64I-MEDIUM-NEXT: addi sp, sp, 16
+; RV64I-MEDIUM-NEXT: ret
+; RV64I-MEDIUM-NEXT: .LBB2_3: # %return.clone
+; RV64I-MEDIUM-NEXT: li a0, 3
+; RV64I-MEDIUM-NEXT: addi sp, sp, 16
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: lower_blockaddress_displ:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: addi sp, sp, -16
+; RV64I-LARGE-NEXT: .Lpcrel_hi2:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI2_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi2)(a1)
+; RV64I-LARGE-NEXT: li a2, 101
+; RV64I-LARGE-NEXT: sd a1, 8(sp)
+; RV64I-LARGE-NEXT: blt a0, a2, .LBB2_3
+; RV64I-LARGE-NEXT: # %bb.1: # %if.then
+; RV64I-LARGE-NEXT: ld a0, 8(sp)
+; RV64I-LARGE-NEXT: jr a0
+; RV64I-LARGE-NEXT: .Ltmp0: # Block address taken
+; RV64I-LARGE-NEXT: .LBB2_2: # %return
+; RV64I-LARGE-NEXT: li a0, 4
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
+; RV64I-LARGE-NEXT: .LBB2_3: # %return.clone
+; RV64I-LARGE-NEXT: li a0, 3
+; RV64I-LARGE-NEXT: addi sp, sp, 16
+; RV64I-LARGE-NEXT: ret
entry:
%x = alloca ptr, align 8
store ptr blockaddress(@lower_blockaddress_displ, %test_block), ptr %x, align 8
@@ -136,6 +252,29 @@ define float @lower_constantpool(float %a) nounwind {
; RV32I-MEDIUM-NEXT: flw fa5, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV32I-MEDIUM-NEXT: fadd.s fa0, fa0, fa5
; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-SMALL-LABEL: lower_constantpool:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: lui a0, %hi(.LCPI3_0)
+; RV64I-SMALL-NEXT: flw fa5, %lo(.LCPI3_0)(a0)
+; RV64I-SMALL-NEXT: fadd.s fa0, fa0, fa5
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: lower_constantpool:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi3:
+; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(.LCPI3_0)
+; RV64I-MEDIUM-NEXT: flw fa5, %pcrel_lo(.Lpcrel_hi3)(a0)
+; RV64I-MEDIUM-NEXT: fadd.s fa0, fa0, fa5
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: lower_constantpool:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi3:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI3_0)
+; RV64I-LARGE-NEXT: flw fa5, %pcrel_lo(.Lpcrel_hi3)(a0)
+; RV64I-LARGE-NEXT: fadd.s fa0, fa0, fa5
+; RV64I-LARGE-NEXT: ret
%1 = fadd float %a, 1.000244140625
ret float %1
}
@@ -157,6 +296,28 @@ define i32 @lower_extern_weak(i32 %a) nounwind {
; RV32I-MEDIUM-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi4)(a0)
; RV32I-MEDIUM-NEXT: lw a0, 0(a0)
; RV32I-MEDIUM-NEXT: ret
+;
+; RV64I-SMALL-LABEL: lower_extern_weak:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: lui a0, %hi(W)
+; RV64I-SMALL-NEXT: lw a0, %lo(W)(a0)
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: lower_extern_weak:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi4:
+; RV64I-MEDIUM-NEXT: auipc a0, %got_pcrel_hi(W)
+; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
+; RV64I-MEDIUM-NEXT: lw a0, 0(a0)
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: lower_extern_weak:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi4:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI4_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
+; RV64I-LARGE-NEXT: lw a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
%1 = load volatile i32, ptr @W
ret i32 %1
}
diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
index 321857b2104eb5..4a6e43c7d2be6a 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
@@ -7,6 +7,8 @@
; RUN: -riscv-enable-sink-fold | FileCheck -check-prefix=RV64I %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs -code-model=medium < %s \
; RUN: -riscv-enable-sink-fold | FileCheck -check-prefix=RV64I-MEDIUM %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs -code-model=large < %s \
+; RUN: -riscv-enable-sink-fold | FileCheck -check-prefix=RV64I-LARGE %s
; We can often fold an ADDI into the offset of load/store instructions:
; (load (addi base, off1), off2) -> (load base, off1+off2)
@@ -51,6 +53,14 @@ define dso_local i64 @load_g_0() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_0)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_g_0:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi0:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI0_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV64I-LARGE-NEXT: ld a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_0
ret i64 %0
@@ -86,6 +96,14 @@ define dso_local i64 @load_g_1() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_1)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_g_1:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi1:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI1_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
+; RV64I-LARGE-NEXT: ld a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_1
ret i64 %0
@@ -121,6 +139,14 @@ define dso_local i64 @load_g_2() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_2)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi2)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_g_2:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi2:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI2_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi2)(a0)
+; RV64I-LARGE-NEXT: ld a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_2
ret i64 %0
@@ -156,6 +182,14 @@ define dso_local i64 @load_g_4() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_4)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_g_4:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi3:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI3_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
+; RV64I-LARGE-NEXT: ld a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_4
ret i64 %0
@@ -190,6 +224,14 @@ define dso_local i64 @load_g_8() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_8)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_g_8:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi4:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI4_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
+; RV64I-LARGE-NEXT: ld a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_8
ret i64 %0
@@ -224,6 +266,14 @@ define dso_local i64 @load_g_16() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_16)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_g_16:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi5:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI5_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
+; RV64I-LARGE-NEXT: ld a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_16
ret i64 %0
@@ -259,6 +309,14 @@ define dso_local void @store_g_4() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_4)
; RV64I-MEDIUM-NEXT: sd zero, %pcrel_lo(.Lpcrel_hi6)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: store_g_4:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi6:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI6_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi6)(a0)
+; RV64I-LARGE-NEXT: sd zero, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
store i64 0, ptr @g_4
ret void
@@ -293,6 +351,14 @@ define dso_local void @store_g_8() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g_8)
; RV64I-MEDIUM-NEXT: sd zero, %pcrel_lo(.Lpcrel_hi7)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: store_g_8:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi7:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI7_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi7)(a0)
+; RV64I-LARGE-NEXT: sd zero, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
store i64 0, ptr @g_8
ret void
@@ -337,6 +403,16 @@ define dso_local void @inc_g_i32() nounwind {
; RV64I-MEDIUM-NEXT: addi a1, a1, 1
; RV64I-MEDIUM-NEXT: sw a1, %pcrel_lo(.Lpcrel_hi8)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: inc_g_i32:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi8:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI8_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi8)(a0)
+; RV64I-LARGE-NEXT: lw a1, 0(a0)
+; RV64I-LARGE-NEXT: addi a1, a1, 1
+; RV64I-LARGE-NEXT: sw a1, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i32, ptr @g_4_i32
%inc = add i32 %0, 1
@@ -377,6 +453,14 @@ define dso_local i32 @load_ga() local_unnamed_addr #0 {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(ga+4)
; RV64I-MEDIUM-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi9)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_ga:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi9:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI9_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV64I-LARGE-NEXT: lw a0, 4(a0)
+; RV64I-LARGE-NEXT: ret
%1 = load i32, ptr getelementptr inbounds ([2 x i32], ptr @ga, i32 0, i32 1), align 4
ret i32 %1
}
@@ -416,6 +500,14 @@ define dso_local i64 @load_ga_8() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(ga_8+8)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi10)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_ga_8:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi10:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI10_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi10)(a0)
+; RV64I-LARGE-NEXT: ld a0, 8(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr getelementptr inbounds ([2 x i64], ptr @ga_8, i32 0, i32 1)
ret i64 %0
@@ -450,6 +542,14 @@ define dso_local i64 @load_ga_16() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(ga_16+8)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi11)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_ga_16:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi11:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI11_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi11)(a0)
+; RV64I-LARGE-NEXT: ld a0, 8(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr getelementptr inbounds ([2 x i64], ptr @ga_16, i32 0, i32 1)
ret i64 %0
@@ -490,6 +590,16 @@ define dso_local ptr @load_ba_1() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(.Ltmp0)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi12)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_ba_1:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp0: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi12:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI12_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi12)(a0)
+; RV64I-LARGE-NEXT: ld a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
label:
@@ -531,6 +641,16 @@ define dso_local ptr @load_ba_2() nounwind {
; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(.Ltmp1+8)
; RV64I-MEDIUM-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi13)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_ba_2:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp1: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi13:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI13_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi13)(a0)
+; RV64I-LARGE-NEXT: ld a0, 8(a0)
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
label:
@@ -575,6 +695,13 @@ define dso_local i64 @load_tl_4() nounwind {
; RV64I-MEDIUM-NEXT: add a0, a0, tp, %tprel_add(tl_4)
; RV64I-MEDIUM-NEXT: ld a0, %tprel_lo(tl_4)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_tl_4:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: lui a0, %tprel_hi(tl_4)
+; RV64I-LARGE-NEXT: add a0, a0, tp, %tprel_add(tl_4)
+; RV64I-LARGE-NEXT: ld a0, %tprel_lo(tl_4)(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @tl_4
ret i64 %0
@@ -610,6 +737,13 @@ define dso_local i64 @load_tl_8() nounwind {
; RV64I-MEDIUM-NEXT: add a0, a0, tp, %tprel_add(tl_8)
; RV64I-MEDIUM-NEXT: ld a0, %tprel_lo(tl_8)(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_tl_8:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: lui a0, %tprel_hi(tl_8)
+; RV64I-LARGE-NEXT: add a0, a0, tp, %tprel_add(tl_8)
+; RV64I-LARGE-NEXT: ld a0, %tprel_lo(tl_8)(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @tl_8
ret i64 %0
@@ -637,6 +771,11 @@ define dso_local i64 @load_const_ok() nounwind {
; RV64I-MEDIUM: # %bb.0: # %entry
; RV64I-MEDIUM-NEXT: ld a0, 2040(zero)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_const_ok:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: ld a0, 2040(zero)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr inttoptr (i32 2040 to ptr)
ret i64 %0
@@ -666,6 +805,11 @@ define dso_local i64 @load_cost_overflow() nounwind {
; RV64I-MEDIUM: # %bb.0: # %entry
; RV64I-MEDIUM-NEXT: ld a0, 2044(zero)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_cost_overflow:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: ld a0, 2044(zero)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i64, ptr inttoptr (i64 2044 to ptr)
ret i64 %0
@@ -695,6 +839,12 @@ define dso_local i32 @load_const_medium() nounwind {
; RV64I-MEDIUM-NEXT: lui a0, 1
; RV64I-MEDIUM-NEXT: lw a0, -16(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_const_medium:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: lui a0, 1
+; RV64I-LARGE-NEXT: lw a0, -16(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i32, ptr inttoptr (i64 4080 to ptr)
ret i32 %0
@@ -729,6 +879,13 @@ define dso_local i32 @load_const_large() nounwind {
; RV64I-MEDIUM-NEXT: addiw a0, a0, -2048
; RV64I-MEDIUM-NEXT: lw a0, 0(a0)
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: load_const_large:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: lui a0, 524288
+; RV64I-LARGE-NEXT: addiw a0, a0, -2048
+; RV64I-LARGE-NEXT: lw a0, 0(a0)
+; RV64I-LARGE-NEXT: ret
entry:
%0 = load i32, ptr inttoptr (i64 2147481600 to ptr)
ret i32 %0
@@ -938,6 +1095,47 @@ define i64 @fold_addi_from_different_bb(i64 %k, i64 %n, ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
; RV64I-MEDIUM-NEXT: addi sp, sp, 48
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: fold_addi_from_different_bb:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: addi sp, sp, -48
+; RV64I-LARGE-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: blez a1, .LBB20_3
+; RV64I-LARGE-NEXT: # %bb.1: # %for.body.lr.ph
+; RV64I-LARGE-NEXT: mv s0, a2
+; RV64I-LARGE-NEXT: mv s1, a1
+; RV64I-LARGE-NEXT: .Lpcrel_hi14:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI20_0)
+; RV64I-LARGE-NEXT: ld s3, %pcrel_lo(.Lpcrel_hi14)(a1)
+; RV64I-LARGE-NEXT: li s2, 0
+; RV64I-LARGE-NEXT: slli a0, a0, 4
+; RV64I-LARGE-NEXT: add s4, a2, a0
+; RV64I-LARGE-NEXT: .LBB20_2: # %for.body
+; RV64I-LARGE-NEXT: # =>This Inner Loop Header: Depth=1
+; RV64I-LARGE-NEXT: mv a0, s0
+; RV64I-LARGE-NEXT: jalr s3
+; RV64I-LARGE-NEXT: ld a0, 8(s4)
+; RV64I-LARGE-NEXT: addi s1, s1, -1
+; RV64I-LARGE-NEXT: add s2, a0, s2
+; RV64I-LARGE-NEXT: bnez s1, .LBB20_2
+; RV64I-LARGE-NEXT: j .LBB20_4
+; RV64I-LARGE-NEXT: .LBB20_3:
+; RV64I-LARGE-NEXT: li s2, 0
+; RV64I-LARGE-NEXT: .LBB20_4: # %for.cond.cleanup
+; RV64I-LARGE-NEXT: mv a0, s2
+; RV64I-LARGE-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
+; RV64I-LARGE-NEXT: addi sp, sp, 48
+; RV64I-LARGE-NEXT: ret
entry:
%cmp4 = icmp sgt i64 %n, 0
br i1 %cmp4, label %for.body.lr.ph, label %for.cond.cleanup
diff --git a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
index eb0e0287d48d7b..0dc4e884cbb104 100644
--- a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
+++ b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
@@ -7,6 +7,8 @@
; RUN: | FileCheck -check-prefixes=RV32I-MEDIUM %s
; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM %s
+; RUN: llc -mtriple=riscv64 -code-model=large -verify-machineinstrs -no-integrated-as < %s \
+; RUN: | FileCheck -check-prefixes=RV64I-LARGE %s
@eg = external global [4000 x i32], align 4
@ewg = extern_weak global [4000 x i32], align 4
@@ -35,6 +37,12 @@ define void @constraint_m_1(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: #APP
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm sideeffect "", "=*m"(ptr elementtype(i32) %a)
ret void
}
@@ -67,6 +75,13 @@ define i32 @constraint_m_2(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: lw a0, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw a0, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
%1 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %a)
ret i32 %1
}
@@ -99,6 +114,13 @@ define i32 @constraint_m_with_offset(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: lw a0, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_offset:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw a0, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
%1 = getelementptr i32, ptr %a, i32 1
%2 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %1)
ret i32 %2
@@ -140,6 +162,16 @@ define void @constraint_m_with_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_global_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi0:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI3_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
ret void
}
@@ -182,6 +214,16 @@ define void @constraint_m_with_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_global_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi1:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI4_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 1))
ret void
}
@@ -224,6 +266,19 @@ define void @constraint_m_with_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_global_3:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi2:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI5_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi2)(a0)
+; RV64I-LARGE-NEXT: lui a1, 2
+; RV64I-LARGE-NEXT: addiw a1, a1, -192
+; RV64I-LARGE-NEXT: add a0, a0, a1
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 2000))
ret void
}
@@ -264,6 +319,16 @@ define void @constraint_m_with_extern_weak_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_extern_weak_global_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi3:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI6_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @ewg)
ret void
}
@@ -306,6 +371,16 @@ define void @constraint_m_with_extern_weak_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_extern_weak_global_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi4:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI7_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 1))
ret void
}
@@ -354,6 +429,19 @@ define void @constraint_m_with_extern_weak_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_extern_weak_global_3:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi5:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI8_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
+; RV64I-LARGE-NEXT: lui a1, 2
+; RV64I-LARGE-NEXT: addiw a1, a1, -192
+; RV64I-LARGE-NEXT: add a0, a0, a1
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 2000))
ret void
}
@@ -402,6 +490,18 @@ define void @constraint_m_with_local_1() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_local_1:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp0: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi6:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI9_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi6)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -456,6 +556,18 @@ define void @constraint_m_with_local_2() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_local_2:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp1: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi7:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI10_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi7)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -510,6 +622,18 @@ define void @constraint_m_with_local_3() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 2000(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_local_3:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp2: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi8:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI11_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi8)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 2000(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -554,6 +678,16 @@ define void @constraint_m_with_multi_operands() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0); sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_multi_operands:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi9:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI12_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0); sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0; sw zero, $1", "=*m,=*m"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
ret void
}
@@ -606,6 +740,19 @@ define void @constraint_m_with_multi_asm() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_multi_asm:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi10:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI13_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi10)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
ret void
@@ -675,6 +822,23 @@ define i32 @constraint_m_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-NEXT: li a0, 1
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_callbr_multi_operands:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi11:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI14_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi11)(a1)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB14_2
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-NEXT: li a0, 0
+; RV64I-LARGE-NEXT: ret
+; RV64I-LARGE-NEXT: .LBB14_2: # Block address taken
+; RV64I-LARGE-NEXT: # %fail
+; RV64I-LARGE-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NEXT: li a0, 1
+; RV64I-LARGE-NEXT: ret
entry:
callbr void asm "sw zero, $0; sw zero, $1; beqz $2, $3", "=*m,=*m,r,!i"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg, i32 %a) to label %normal [label %fail]
@@ -765,6 +929,27 @@ define i32 @constraint_m_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-NEXT: li a0, 1
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_m_with_multi_callbr_asm:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi12:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI15_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi12)(a1)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); beqz a0, .LBB15_3
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); beqz a0, .LBB15_3
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-NEXT: li a0, 0
+; RV64I-LARGE-NEXT: ret
+; RV64I-LARGE-NEXT: .LBB15_3: # Block address taken
+; RV64I-LARGE-NEXT: # %fail
+; RV64I-LARGE-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NEXT: li a0, 1
+; RV64I-LARGE-NEXT: ret
entry:
callbr void asm "sw zero, $0; beqz $1, $2", "=*m,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
@@ -802,6 +987,12 @@ define void @constraint_o_1(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: #APP
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm sideeffect "", "=*o"(ptr elementtype(i32) %a)
ret void
}
@@ -834,6 +1025,13 @@ define i32 @constraint_o_2(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: lw a0, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw a0, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
%1 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %a)
ret i32 %1
}
@@ -866,6 +1064,13 @@ define i32 @constraint_o_with_offset(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: lw a0, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_offset:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw a0, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
%1 = getelementptr i32, ptr %a, i32 1
%2 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %1)
ret i32 %2
@@ -907,6 +1112,16 @@ define void @constraint_o_with_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_global_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi13:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI19_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi13)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
ret void
}
@@ -949,6 +1164,16 @@ define void @constraint_o_with_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_global_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi14:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI20_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi14)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 1))
ret void
}
@@ -991,6 +1216,19 @@ define void @constraint_o_with_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_global_3:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi15:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI21_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi15)(a0)
+; RV64I-LARGE-NEXT: lui a1, 2
+; RV64I-LARGE-NEXT: addiw a1, a1, -192
+; RV64I-LARGE-NEXT: add a0, a0, a1
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 2000))
ret void
}
@@ -1031,6 +1269,16 @@ define void @constraint_o_with_extern_weak_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_extern_weak_global_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi16:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI22_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi16)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @ewg)
ret void
}
@@ -1073,6 +1321,16 @@ define void @constraint_o_with_extern_weak_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_extern_weak_global_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi17:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI23_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi17)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 1))
ret void
}
@@ -1121,6 +1379,19 @@ define void @constraint_o_with_extern_weak_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_extern_weak_global_3:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi18:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI24_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi18)(a0)
+; RV64I-LARGE-NEXT: lui a1, 2
+; RV64I-LARGE-NEXT: addiw a1, a1, -192
+; RV64I-LARGE-NEXT: add a0, a0, a1
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 2000))
ret void
}
@@ -1161,6 +1432,16 @@ define void @constraint_o_with_multi_operands() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_multi_operands:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi19:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI25_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi19)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0 \n sw zero, $1", "=*o,=*o"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
ret void
}
@@ -1213,6 +1494,19 @@ define void @constraint_o_with_multi_asm() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_multi_asm:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi20:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI26_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi20)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
ret void
@@ -1282,6 +1576,23 @@ define i32 @constraint_o_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-NEXT: li a0, 1
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_callbr_multi_operands:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi21:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI27_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi21)(a1)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB27_2
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-NEXT: li a0, 0
+; RV64I-LARGE-NEXT: ret
+; RV64I-LARGE-NEXT: .LBB27_2: # Block address taken
+; RV64I-LARGE-NEXT: # %fail
+; RV64I-LARGE-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NEXT: li a0, 1
+; RV64I-LARGE-NEXT: ret
entry:
callbr void asm "sw zero, $0; sw zero, $1; beqz $2, $3", "=*m,=*m,r,!i"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg, i32 %a) to label %normal [label %fail]
@@ -1372,6 +1683,27 @@ define i32 @constraint_o_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-NEXT: li a0, 1
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_multi_callbr_asm:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi22:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI28_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi22)(a1)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); beqz a0, .LBB28_3
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); beqz a0, .LBB28_3
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-NEXT: li a0, 0
+; RV64I-LARGE-NEXT: ret
+; RV64I-LARGE-NEXT: .LBB28_3: # Block address taken
+; RV64I-LARGE-NEXT: # %fail
+; RV64I-LARGE-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NEXT: li a0, 1
+; RV64I-LARGE-NEXT: ret
entry:
callbr void asm "sw zero, $0; beqz $1, $2", "=*o,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
@@ -1429,6 +1761,18 @@ define void @constraint_o_with_local_1() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_local_1:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp3: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi23:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI29_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi23)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -1483,6 +1827,18 @@ define void @constraint_o_with_local_2() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 4(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_local_2:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp4: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi24:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI30_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi24)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 4(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -1537,6 +1893,18 @@ define void @constraint_o_with_local_3() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 2000(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_o_with_local_3:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp5: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi25:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI31_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi25)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 2000(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -1585,6 +1953,16 @@ define void @constraint_A(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: lb s1, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sb s0, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lb s1, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
tail call void asm sideeffect "sb s0, $0", "*A"(ptr elementtype(i8) %a)
tail call void asm sideeffect "lb s1, $0", "*A"(ptr elementtype(i8) %a)
ret void
@@ -1622,6 +2000,14 @@ define i32 @constraint_A_with_offset(ptr %a) nounwind {
; RV64I-MEDIUM-NEXT: lw a0, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_offset:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: addi a0, a0, 4
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw a0, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
%1 = getelementptr i32, ptr %a, i32 1
%2 = tail call i32 asm "lw $0, $1", "=r,*A"(ptr elementtype(i32) %1)
ret i32 %2
@@ -1665,6 +2051,16 @@ define void @constraint_A_with_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_global_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi26:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI34_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi26)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @eg)
ret void
}
@@ -1707,6 +2103,17 @@ define void @constraint_A_with_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_global_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi27:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI35_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi27)(a0)
+; RV64I-LARGE-NEXT: addi a0, a0, 4
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 1))
ret void
}
@@ -1749,6 +2156,19 @@ define void @constraint_A_with_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_global_3:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi28:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI36_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi28)(a0)
+; RV64I-LARGE-NEXT: lui a1, 2
+; RV64I-LARGE-NEXT: addiw a1, a1, -192
+; RV64I-LARGE-NEXT: add a0, a0, a1
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 2000))
ret void
}
@@ -1791,6 +2211,16 @@ define void @constraint_A_with_extern_weak_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_extern_weak_global_1:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi29:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI37_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi29)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @ewg)
ret void
}
@@ -1835,6 +2265,17 @@ define void @constraint_A_with_extern_weak_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_extern_weak_global_2:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi30:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI38_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi30)(a0)
+; RV64I-LARGE-NEXT: addi a0, a0, 4
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 1))
ret void
}
@@ -1883,6 +2324,19 @@ define void @constraint_A_with_extern_weak_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_extern_weak_global_3:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi31:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI39_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi31)(a0)
+; RV64I-LARGE-NEXT: lui a1, 2
+; RV64I-LARGE-NEXT: addiw a1, a1, -192
+; RV64I-LARGE-NEXT: add a0, a0, a1
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 2000))
ret void
}
@@ -1925,6 +2379,16 @@ define void @constraint_A_with_multi_operands() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_multi_operands:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi32:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI40_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi32)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0) \n sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0 \n sw zero, $1", "=*A,=*A"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
ret void
}
@@ -1979,6 +2443,19 @@ define void @constraint_A_with_multi_asm() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_multi_asm:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: .Lpcrel_hi33:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI41_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi33)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @eg)
call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @eg)
ret void
@@ -2050,6 +2527,23 @@ define i32 @constraint_A_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-NEXT: li a0, 1
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_callbr_multi_operands:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi34:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI42_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi34)(a1)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB42_2
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-NEXT: li a0, 0
+; RV64I-LARGE-NEXT: ret
+; RV64I-LARGE-NEXT: .LBB42_2: # Block address taken
+; RV64I-LARGE-NEXT: # %fail
+; RV64I-LARGE-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NEXT: li a0, 1
+; RV64I-LARGE-NEXT: ret
entry:
callbr void asm "sw zero, $0; sw zero, $1; beqz $2, $3", "*A,*A,r,!i"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg, i32 %a) to label %normal [label %fail]
@@ -2142,6 +2636,27 @@ define i32 @constraint_A_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-NEXT: li a0, 1
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_multi_callbr_asm:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Lpcrel_hi35:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI43_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi35)(a1)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); beqz a0, .LBB43_3
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: sw zero, 0(a1); beqz a0, .LBB43_3
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-NEXT: li a0, 0
+; RV64I-LARGE-NEXT: ret
+; RV64I-LARGE-NEXT: .LBB43_3: # Block address taken
+; RV64I-LARGE-NEXT: # %fail
+; RV64I-LARGE-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NEXT: li a0, 1
+; RV64I-LARGE-NEXT: ret
entry:
callbr void asm "sw zero, $0; beqz $1, $2", "=*A,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
@@ -2201,6 +2716,18 @@ define void @constraint_A_with_local_1() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_local_1:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp6: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi36:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI44_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi36)(a0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -2255,6 +2782,19 @@ define void @constraint_A_with_local_2() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_local_2:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp7: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi37:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI45_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi37)(a0)
+; RV64I-LARGE-NEXT: addi a0, a0, 4
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -2309,6 +2849,19 @@ define void @constraint_A_with_local_3() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, 0(a0)
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: constraint_A_with_local_3:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: .Ltmp8: # Block address taken
+; RV64I-LARGE-NEXT: # %bb.1: # %label
+; RV64I-LARGE-NEXT: .Lpcrel_hi38:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI46_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi38)(a0)
+; RV64I-LARGE-NEXT: addi a0, a0, 2000
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
>From 42531a61d2376cee063454a244813fb313ef31a1 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 13 Dec 2023 10:57:54 +0800
Subject: [PATCH 2/7] Alphabetize forward declaration
---
llvm/lib/Target/RISCV/RISCVConstantPoolValue.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
index 8edd95e9a065fd..5f894e38dc6d35 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -19,9 +19,9 @@
namespace llvm {
-class LLVMContext;
-class GlobalValue;
class BlockAddress;
+class GlobalValue;
+class LLVMContext;
namespace RISCVCP {
>From c30d948788ae8aeaa246e6effb7b17b454f0d691 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 13 Dec 2023 13:04:52 +0800
Subject: [PATCH 3/7] Remove unused Modifier
---
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 11 +-----
.../Target/RISCV/RISCVConstantPoolValue.cpp | 36 +++++--------------
.../lib/Target/RISCV/RISCVConstantPoolValue.h | 31 ++++------------
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
4 files changed, 17 insertions(+), 63 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 6308d1f574b4d0..26e5e63db322d9 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -985,15 +985,6 @@ 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);
@@ -1012,7 +1003,7 @@ void RISCVAsmPrinter::emitMachineConstantPoolValue(
}
const MCExpr *Expr = MCSymbolRefExpr::create(
- MCSym, getModifierVariantKind(RCPV->getModifier()), OutContext);
+ MCSym, MCSymbolRefExpr::VK_None, 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
index 398dfbd9bb6594..c47ad35d189f03 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
@@ -22,37 +22,22 @@
using namespace llvm;
RISCVConstantPoolValue::RISCVConstantPoolValue(
- LLVMContext &C, RISCVCP::RISCVCPKind Kind,
- RISCVCP::RISCVCPModifier Modifier)
- : MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind),
- Modifier(Modifier) {}
+ LLVMContext &C, RISCVCP::RISCVCPKind Kind)
+ : MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind) {}
RISCVConstantPoolValue::RISCVConstantPoolValue(
- Type *Ty, RISCVCP::RISCVCPKind Kind, RISCVCP::RISCVCPModifier Modifier)
- : MachineConstantPoolValue(Ty), Kind(Kind), Modifier(Modifier) {}
+ Type *Ty, RISCVCP::RISCVCPKind Kind)
+ : MachineConstantPoolValue(Ty), Kind(Kind) {}
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) {}
+ : RISCVConstantPoolValue(Ty, Kind), CVal(GV) {}
RISCVConstantPoolConstant *
RISCVConstantPoolConstant::Create(const GlobalValue *GV,
@@ -78,7 +63,6 @@ void RISCVConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
void RISCVConstantPoolConstant::print(raw_ostream &O) const {
O << CVal->getName();
- RISCVConstantPoolValue::print(O);
}
const GlobalValue *RISCVConstantPoolConstant::getGlobalValue() const {
@@ -90,13 +74,12 @@ const BlockAddress *RISCVConstantPoolConstant::getBlockAddress() const {
}
RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(
- LLVMContext &C, StringRef s, RISCVCP::RISCVCPModifier Modifier)
- : RISCVConstantPoolValue(C, RISCVCP::ExtSymbol, Modifier), S(s) {}
+ LLVMContext &C, StringRef s)
+ : RISCVConstantPoolValue(C, RISCVCP::ExtSymbol), S(s) {}
RISCVConstantPoolSymbol *
-RISCVConstantPoolSymbol::Create(LLVMContext &C, StringRef s,
- RISCVCP::RISCVCPModifier Modifier) {
- return new RISCVConstantPoolSymbol(C, s, Modifier);
+RISCVConstantPoolSymbol::Create(LLVMContext &C, StringRef s) {
+ return new RISCVConstantPoolSymbol(C, s);
}
int RISCVConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
@@ -110,5 +93,4 @@ void RISCVConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
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
index 5f894e38dc6d35..901e09bee280a4 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -26,23 +26,16 @@ class LLVMContext;
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(LLVMContext &C, RISCVCP::RISCVCPKind Kind);
- RISCVConstantPoolValue(Type *Ty, RISCVCP::RISCVCPKind Kind,
- RISCVCP::RISCVCPModifier Modifier);
+ RISCVConstantPoolValue(Type *Ty, RISCVCP::RISCVCPKind Kind);
template <typename Derived>
int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
@@ -64,10 +57,6 @@ class RISCVConstantPoolValue : public MachineConstantPoolValue {
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; }
@@ -76,12 +65,6 @@ class RISCVConstantPoolValue : public MachineConstantPoolValue {
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 {
@@ -107,7 +90,7 @@ class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
void print(raw_ostream &O) const override;
bool equals(const RISCVConstantPoolConstant *A) const {
- return CVal == A->CVal && RISCVConstantPoolValue::equals(A);
+ return CVal == A->CVal;
}
static bool classof(const RISCVConstantPoolValue *RCPV) {
@@ -118,12 +101,10 @@ class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
const std::string S;
- RISCVConstantPoolSymbol(LLVMContext &C, StringRef s,
- RISCVCP::RISCVCPModifier Modifier);
+ RISCVConstantPoolSymbol(LLVMContext &C, StringRef s);
public:
- static RISCVConstantPoolSymbol *Create(LLVMContext &C, StringRef s,
- RISCVCP ::RISCVCPModifier Modifier);
+ static RISCVConstantPoolSymbol *Create(LLVMContext &C, StringRef s);
std::string getSymbol() const { return S; }
@@ -135,7 +116,7 @@ class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
void print(raw_ostream &O) const override;
bool equals(const RISCVConstantPoolSymbol *A) const {
- return S == A->S && RISCVConstantPoolValue::equals(A);
+ return S == A->S;
}
static bool classof(const RISCVConstantPoolValue *RCPV) {
return RCPV->isExtSymbol();
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index e523995a909f59..95d42ed792c8c8 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6457,7 +6457,7 @@ static SDValue getLargeAddr(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG) {
MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N)) {
RISCVConstantPoolSymbol *CPV = RISCVConstantPoolSymbol::Create(
- *DAG.getContext(), S->getSymbol(), RISCVCP::None);
+ *DAG.getContext(), S->getSymbol());
SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
return DAG.getLoad(
>From 11ba318d4ebd0a180b96f619bf0c5f3232edf66e Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 13 Dec 2023 14:00:22 +0800
Subject: [PATCH 4/7] clang-foramt
---
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 4 ++--
.../Target/RISCV/RISCVConstantPoolValue.cpp | 19 ++++++++-----------
.../lib/Target/RISCV/RISCVConstantPoolValue.h | 4 +---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++--
4 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 26e5e63db322d9..157703c5ed38f8 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -1002,8 +1002,8 @@ void RISCVAsmPrinter::emitMachineConstantPoolValue(
MCSym = GetExternalSymbolSymbol(Sym);
}
- const MCExpr *Expr = MCSymbolRefExpr::create(
- MCSym, MCSymbolRefExpr::VK_None, OutContext);
+ const MCExpr *Expr =
+ MCSymbolRefExpr::create(MCSym, MCSymbolRefExpr::VK_None, 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
index c47ad35d189f03..e548e88fffc1ed 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
@@ -21,12 +21,12 @@
using namespace llvm;
-RISCVConstantPoolValue::RISCVConstantPoolValue(
- LLVMContext &C, RISCVCP::RISCVCPKind Kind)
+RISCVConstantPoolValue::RISCVConstantPoolValue(LLVMContext &C,
+ RISCVCP::RISCVCPKind Kind)
: MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind) {}
-RISCVConstantPoolValue::RISCVConstantPoolValue(
- Type *Ty, RISCVCP::RISCVCPKind Kind)
+RISCVConstantPoolValue::RISCVConstantPoolValue(Type *Ty,
+ RISCVCP::RISCVCPKind Kind)
: MachineConstantPoolValue(Ty), Kind(Kind) {}
int RISCVConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
@@ -73,12 +73,11 @@ const BlockAddress *RISCVConstantPoolConstant::getBlockAddress() const {
return dyn_cast_or_null<BlockAddress>(CVal);
}
-RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(
- LLVMContext &C, StringRef s)
+RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(LLVMContext &C, StringRef s)
: RISCVConstantPoolValue(C, RISCVCP::ExtSymbol), S(s) {}
-RISCVConstantPoolSymbol *
-RISCVConstantPoolSymbol::Create(LLVMContext &C, StringRef s) {
+RISCVConstantPoolSymbol *RISCVConstantPoolSymbol::Create(LLVMContext &C,
+ StringRef s) {
return new RISCVConstantPoolSymbol(C, s);
}
@@ -91,6 +90,4 @@ void RISCVConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
ID.AddString(S);
}
-void RISCVConstantPoolSymbol::print(raw_ostream &O) const {
- O << S;
-}
+void RISCVConstantPoolSymbol::print(raw_ostream &O) const { O << S; }
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
index 901e09bee280a4..ca6c714e32ad02 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -115,9 +115,7 @@ class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
void print(raw_ostream &O) const override;
- bool equals(const RISCVConstantPoolSymbol *A) const {
- return S == A->S;
- }
+ bool equals(const RISCVConstantPoolSymbol *A) const { return S == A->S; }
static bool classof(const RISCVConstantPoolValue *RCPV) {
return RCPV->isExtSymbol();
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 95d42ed792c8c8..0572dea571d855 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6456,8 +6456,8 @@ static SDValue getLargeAddr(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG) {
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());
+ RISCVConstantPoolSymbol *CPV =
+ RISCVConstantPoolSymbol::Create(*DAG.getContext(), S->getSymbol());
SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
return DAG.getLoad(
>From c8fed1ee70bfcc12ae1b2e5f0eaca7c89bb1ed36 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 13 Dec 2023 15:08:34 +0800
Subject: [PATCH 5/7] Rewrite the code to avoid adding unneeded function.
Since getLargeAddr is reused before, that getTargetNode must have
`ExternalSymbolSDNode` version during template instantiation.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 64 ++++++++++++---------
1 file changed, 37 insertions(+), 27 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 0572dea571d855..89d7d5e8b23598 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6432,37 +6432,45 @@ 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.");
+static SDValue getLargeGlobalAddress(GlobalAddressSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG) {
+ RISCVConstantPoolConstant *CPV =
+ RISCVConstantPoolConstant::Create(N->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()));
+}
+
+static SDValue getLargeBlockAddress(BlockAddressSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG) {
+ RISCVConstantPoolConstant *CPV = RISCVConstantPoolConstant::Create(
+ N->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()));
+}
+
+static SDValue getLargeExternalSymbol(ExternalSymbolSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG) {
+ RISCVConstantPoolSymbol *CPV =
+ RISCVConstantPoolSymbol::Create(*DAG.getContext(), N->getSymbol());
+ 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()));
}
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()));
+ return getLargeGlobalAddress(G, DL, Ty, DAG);
} 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());
- 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()));
+ return getLargeBlockAddress(B, DL, Ty, DAG);
} else {
// Using pc-relative mode for other node type.
SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
@@ -17533,10 +17541,12 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// split it and then direct call can be matched by PseudoCALL.
if (getTargetMachine().getCodeModel() == CodeModel::Large) {
if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
- Callee = getLargeAddr(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
+ Callee =
+ getLargeGlobalAddress(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
} else if (ExternalSymbolSDNode *S =
dyn_cast<ExternalSymbolSDNode>(Callee)) {
- Callee = getLargeAddr(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
+ Callee =
+ getLargeExternalSymbol(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
}
} else {
if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
>From 522da43d107933803167f6447ff29b076fa7c230 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 13 Dec 2023 16:09:06 +0800
Subject: [PATCH 6/7] Address topperc's comments
---
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 4 ++--
llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp | 11 +++++------
llvm/lib/Target/RISCV/RISCVConstantPoolValue.h | 12 ++++++------
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 6 +++---
4 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 157703c5ed38f8..81401daef681f0 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -991,10 +991,10 @@ void RISCVAsmPrinter::emitMachineConstantPoolValue(
MCSymbol *MCSym;
if (RCPV->isGlobalValue()) {
- auto GV = cast<RISCVConstantPoolConstant>(RCPV)->getGlobalValue();
+ auto *GV = cast<RISCVConstantPoolConstant>(RCPV)->getGlobalValue();
MCSym = getSymbol(GV);
} else if (RCPV->isBlockAddress()) {
- auto BA = cast<RISCVConstantPoolConstant>(RCPV)->getBlockAddress();
+ auto *BA = cast<RISCVConstantPoolConstant>(RCPV)->getBlockAddress();
MCSym = GetBlockAddressSymbol(BA);
} else {
assert(RCPV->isExtSymbol() && "unrecognized constant pool value");
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
index e548e88fffc1ed..ddc85ae31fa52f 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
@@ -40,15 +40,14 @@ RISCVConstantPoolConstant::RISCVConstantPoolConstant(Type *Ty,
: RISCVConstantPoolValue(Ty, Kind), CVal(GV) {}
RISCVConstantPoolConstant *
-RISCVConstantPoolConstant::Create(const GlobalValue *GV,
- RISCVCP::RISCVCPKind Kind) {
- return new RISCVConstantPoolConstant(GV->getType(), GV, Kind);
+RISCVConstantPoolConstant::Create(const GlobalValue *GV) {
+ return new RISCVConstantPoolConstant(GV->getType(), GV, RISCVCP::GlobalValue);
}
RISCVConstantPoolConstant *
-RISCVConstantPoolConstant::Create(const Constant *C,
- RISCVCP::RISCVCPKind Kind) {
- return new RISCVConstantPoolConstant(C->getType(), C, Kind);
+RISCVConstantPoolConstant::Create(const BlockAddress *BA) {
+ return new RISCVConstantPoolConstant(BA->getType(), BA,
+ RISCVCP::BlockAddress);
}
int RISCVConstantPoolConstant::getExistingMachineCPValue(
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
index ca6c714e32ad02..aa08cc57c10f74 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -13,6 +13,7 @@
#ifndef LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
#define LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
@@ -74,10 +75,8 @@ class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
RISCVCP::RISCVCPKind Kind);
public:
- static RISCVConstantPoolConstant *Create(const GlobalValue *GV,
- RISCVCP::RISCVCPKind Kind);
- static RISCVConstantPoolConstant *Create(const Constant *C,
- RISCVCP::RISCVCPKind Kind);
+ static RISCVConstantPoolConstant *Create(const GlobalValue *GV);
+ static RISCVConstantPoolConstant *Create(const BlockAddress *BA);
const GlobalValue *getGlobalValue() const;
const BlockAddress *getBlockAddress() const;
@@ -99,14 +98,14 @@ class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
};
class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
- const std::string S;
+ const StringRef S;
RISCVConstantPoolSymbol(LLVMContext &C, StringRef s);
public:
static RISCVConstantPoolSymbol *Create(LLVMContext &C, StringRef s);
- std::string getSymbol() const { return S; }
+ StringRef getSymbol() const { return S; }
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
@@ -116,6 +115,7 @@ class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
void print(raw_ostream &O) const override;
bool equals(const RISCVConstantPoolSymbol *A) const { return S == A->S; }
+
static bool classof(const RISCVConstantPoolValue *RCPV) {
return RCPV->isExtSymbol();
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 89d7d5e8b23598..bf8993f2123a51 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6435,7 +6435,7 @@ static SDValue getTargetNode(JumpTableSDNode *N, const SDLoc &DL, EVT Ty,
static SDValue getLargeGlobalAddress(GlobalAddressSDNode *N, SDLoc DL, EVT Ty,
SelectionDAG &DAG) {
RISCVConstantPoolConstant *CPV =
- RISCVConstantPoolConstant::Create(N->getGlobal(), RISCVCP::GlobalValue);
+ RISCVConstantPoolConstant::Create(N->getGlobal());
SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
return DAG.getLoad(
@@ -6445,8 +6445,8 @@ static SDValue getLargeGlobalAddress(GlobalAddressSDNode *N, SDLoc DL, EVT Ty,
static SDValue getLargeBlockAddress(BlockAddressSDNode *N, SDLoc DL, EVT Ty,
SelectionDAG &DAG) {
- RISCVConstantPoolConstant *CPV = RISCVConstantPoolConstant::Create(
- N->getBlockAddress(), RISCVCP::BlockAddress);
+ RISCVConstantPoolConstant *CPV =
+ RISCVConstantPoolConstant::Create(N->getBlockAddress());
SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
return DAG.getLoad(
>From 4e3f58246836ec66b6f824454270faa44d3b5ab4 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Thu, 21 Dec 2023 15:47:52 +0800
Subject: [PATCH 7/7] Move `enum RISCVCPKind` into the class that uses it.
---
.../Target/RISCV/RISCVConstantPoolValue.cpp | 12 ++++-----
.../lib/Target/RISCV/RISCVConstantPoolValue.h | 25 ++++++++-----------
2 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
index ddc85ae31fa52f..bd674094ecc891 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
@@ -22,11 +22,11 @@
using namespace llvm;
RISCVConstantPoolValue::RISCVConstantPoolValue(LLVMContext &C,
- RISCVCP::RISCVCPKind Kind)
+ RISCVCPKind Kind)
: MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind) {}
RISCVConstantPoolValue::RISCVConstantPoolValue(Type *Ty,
- RISCVCP::RISCVCPKind Kind)
+ RISCVCPKind Kind)
: MachineConstantPoolValue(Ty), Kind(Kind) {}
int RISCVConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
@@ -36,18 +36,18 @@ int RISCVConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
RISCVConstantPoolConstant::RISCVConstantPoolConstant(Type *Ty,
const Constant *GV,
- RISCVCP::RISCVCPKind Kind)
+ RISCVCPKind Kind)
: RISCVConstantPoolValue(Ty, Kind), CVal(GV) {}
RISCVConstantPoolConstant *
RISCVConstantPoolConstant::Create(const GlobalValue *GV) {
- return new RISCVConstantPoolConstant(GV->getType(), GV, RISCVCP::GlobalValue);
+ return new RISCVConstantPoolConstant(GV->getType(), GV, RISCVCPKind::GlobalValue);
}
RISCVConstantPoolConstant *
RISCVConstantPoolConstant::Create(const BlockAddress *BA) {
return new RISCVConstantPoolConstant(BA->getType(), BA,
- RISCVCP::BlockAddress);
+ RISCVCPKind::BlockAddress);
}
int RISCVConstantPoolConstant::getExistingMachineCPValue(
@@ -73,7 +73,7 @@ const BlockAddress *RISCVConstantPoolConstant::getBlockAddress() const {
}
RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(LLVMContext &C, StringRef s)
- : RISCVConstantPoolValue(C, RISCVCP::ExtSymbol), S(s) {}
+ : RISCVConstantPoolValue(C, RISCVCPKind::ExtSymbol), S(s) {}
RISCVConstantPoolSymbol *RISCVConstantPoolSymbol::Create(LLVMContext &C,
StringRef s) {
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
index aa08cc57c10f74..85259a951e02b5 100644
--- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -24,19 +24,14 @@ class BlockAddress;
class GlobalValue;
class LLVMContext;
-namespace RISCVCP {
-
-enum RISCVCPKind { ExtSymbol, GlobalValue, BlockAddress };
-} // end namespace RISCVCP
-
/// A RISCV-specific constant pool value.
class RISCVConstantPoolValue : public MachineConstantPoolValue {
- RISCVCP::RISCVCPKind Kind;
-
protected:
- RISCVConstantPoolValue(LLVMContext &C, RISCVCP::RISCVCPKind Kind);
+ enum class RISCVCPKind { ExtSymbol, GlobalValue, BlockAddress };
- RISCVConstantPoolValue(Type *Ty, RISCVCP::RISCVCPKind Kind);
+ RISCVConstantPoolValue(LLVMContext &C, RISCVCPKind Kind);
+
+ RISCVConstantPoolValue(Type *Ty, RISCVCPKind Kind);
template <typename Derived>
int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
@@ -55,12 +50,14 @@ class RISCVConstantPoolValue : public MachineConstantPoolValue {
return -1;
}
+private:
+ RISCVCPKind Kind;
+
public:
~RISCVConstantPoolValue() = default;
-
- bool isExtSymbol() const { return Kind == RISCVCP::ExtSymbol; }
- bool isGlobalValue() const { return Kind == RISCVCP::GlobalValue; }
- bool isBlockAddress() const { return Kind == RISCVCP::BlockAddress; }
+ bool isExtSymbol() const { return Kind == RISCVCPKind::ExtSymbol; }
+ bool isGlobalValue() const { return Kind == RISCVCPKind::GlobalValue; }
+ bool isBlockAddress() const { return Kind == RISCVCPKind::BlockAddress; }
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
@@ -72,7 +69,7 @@ class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
const Constant *CVal;
RISCVConstantPoolConstant(Type *Ty, const Constant *GV,
- RISCVCP::RISCVCPKind Kind);
+ RISCVCPKind Kind);
public:
static RISCVConstantPoolConstant *Create(const GlobalValue *GV);
More information about the llvm-commits
mailing list