[llvm] fef84c5 - [RISCV] Support the large code model. (#70308)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 8 18:15:11 PDT 2024
Author: Jim Lin
Date: 2024-09-09T09:15:07+08:00
New Revision: fef84c56dcd93fc63aa61a1313f0f5465e104291
URL: https://github.com/llvm/llvm-project/commit/fef84c56dcd93fc63aa61a1313f0f5465e104291
DIFF: https://github.com/llvm/llvm-project/commit/fef84c56dcd93fc63aa61a1313f0f5465e104291.diff
LOG: [RISCV] Support the large code model. (#70308)
Implement large code model for GlobalAddressSDNode 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>
Added:
llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
Modified:
llvm/lib/Target/RISCV/CMakeLists.txt
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
llvm/test/CodeGen/RISCV/calls.ll
llvm/test/CodeGen/RISCV/codemodel-lowering.ll
llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index aef0e4fbbf5847..124bc239451aed 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -31,6 +31,7 @@ add_llvm_target(RISCVCodeGen
RISCVAsmPrinter.cpp
RISCVCallingConv.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 24bca2da652d0e..69ab49de1dacad 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -17,6 +17,7 @@
#include "MCTargetDesc/RISCVMatInt.h"
#include "MCTargetDesc/RISCVTargetStreamer.h"
#include "RISCV.h"
+#include "RISCVConstantPoolValue.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVTargetMachine.h"
#include "TargetInfo/RISCVTargetInfo.h"
@@ -77,6 +78,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,
@@ -1080,3 +1083,23 @@ bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
}
return false;
}
+
+void RISCVAsmPrinter::emitMachineConstantPoolValue(
+ MachineConstantPoolValue *MCPV) {
+ auto *RCPV = static_cast<RISCVConstantPoolValue *>(MCPV);
+ MCSymbol *MCSym;
+
+ if (RCPV->isGlobalValue()) {
+ auto *GV = RCPV->getGlobalValue();
+ MCSym = getSymbol(GV);
+ } else {
+ assert(RCPV->isExtSymbol() && "unrecognized constant pool type");
+ auto Sym = RCPV->getSymbol();
+ MCSym = GetExternalSymbolSymbol(Sym);
+ }
+
+ 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
new file mode 100644
index 00000000000000..be925a9c71a348
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
@@ -0,0 +1,81 @@
+//===------- 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(Type *Ty, const GlobalValue *GV)
+ : MachineConstantPoolValue(Ty), GV(GV), Kind(RISCVCPKind::GlobalValue) {}
+
+RISCVConstantPoolValue::RISCVConstantPoolValue(LLVMContext &C, StringRef S)
+ : MachineConstantPoolValue(Type::getInt64Ty(C)), S(S),
+ Kind(RISCVCPKind::ExtSymbol) {}
+
+RISCVConstantPoolValue *RISCVConstantPoolValue::Create(const GlobalValue *GV) {
+ return new RISCVConstantPoolValue(GV->getType(), GV);
+}
+
+RISCVConstantPoolValue *RISCVConstantPoolValue::Create(LLVMContext &C,
+ StringRef S) {
+ return new RISCVConstantPoolValue(C, S);
+}
+
+int RISCVConstantPoolValue::getExistingMachineCPValue(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 (equals(CPV))
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void RISCVConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
+ if (isGlobalValue())
+ ID.AddPointer(GV);
+ else {
+ assert(isExtSymbol() && "unrecognized constant pool type");
+ ID.AddString(S);
+ }
+}
+
+void RISCVConstantPoolValue::print(raw_ostream &O) const {
+ if (isGlobalValue())
+ O << GV->getName();
+ else {
+ assert(isExtSymbol() && "unrecognized constant pool type");
+ O << S;
+ }
+}
+
+bool RISCVConstantPoolValue::equals(const RISCVConstantPoolValue *A) const {
+ if (isGlobalValue() && A->isGlobalValue())
+ return GV == A->GV;
+ if (isExtSymbol() && A->isExtSymbol())
+ return S == A->S;
+
+ return false;
+}
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
new file mode 100644
index 00000000000000..b69904d661fbef
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -0,0 +1,63 @@
+//===--- 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/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class BlockAddress;
+class GlobalValue;
+class LLVMContext;
+
+/// A RISCV-specific constant pool value.
+class RISCVConstantPoolValue : public MachineConstantPoolValue {
+ const GlobalValue *GV;
+ const StringRef S;
+
+ RISCVConstantPoolValue(Type *Ty, const GlobalValue *GV);
+ RISCVConstantPoolValue(LLVMContext &C, StringRef S);
+
+private:
+ enum class RISCVCPKind { ExtSymbol, GlobalValue };
+ RISCVCPKind Kind;
+
+public:
+ ~RISCVConstantPoolValue() = default;
+
+ static RISCVConstantPoolValue *Create(const GlobalValue *GV);
+ static RISCVConstantPoolValue *Create(LLVMContext &C, StringRef S);
+
+ bool isGlobalValue() const { return Kind == RISCVCPKind::GlobalValue; }
+ bool isExtSymbol() const { return Kind == RISCVCPKind::ExtSymbol; }
+
+ const GlobalValue *getGlobalValue() const { return GV; }
+ StringRef 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 RISCVConstantPoolValue *A) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 636de1e69432d6..38dae970c9e051 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"
@@ -7518,6 +7519,27 @@ static SDValue getTargetNode(JumpTableSDNode *N, const SDLoc &DL, EVT Ty,
return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
}
+static SDValue getLargeGlobalAddress(GlobalAddressSDNode *N, const SDLoc &DL,
+ EVT Ty, SelectionDAG &DAG) {
+ RISCVConstantPoolValue *CPV = RISCVConstantPoolValue::Create(N->getGlobal());
+ 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, const SDLoc &DL,
+ EVT Ty, SelectionDAG &DAG) {
+ RISCVConstantPoolValue *CPV =
+ RISCVConstantPoolValue::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>
SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
bool IsLocal, bool IsExternWeak) const {
@@ -7586,6 +7608,14 @@ 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: {
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N))
+ return getLargeGlobalAddress(G, DL, Ty, DAG);
+
+ // Using pc-relative mode for other node type.
+ SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
+ return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr);
+ }
}
}
@@ -19590,7 +19620,12 @@ 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)) {
+ if (getTargetMachine().getCodeModel() == CodeModel::Large) {
+ if (auto *S = dyn_cast<GlobalAddressSDNode>(Callee))
+ Callee = getLargeGlobalAddress(S, DL, PtrVT, DAG);
+ else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee))
+ Callee = getLargeExternalSymbol(S, DL, PtrVT, DAG);
+ } else if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
const GlobalValue *GV = S->getGlobal();
Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, RISCVII::MO_CALL);
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
index b7d112ecfc72a7..cba191263fc025 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
@@ -161,7 +161,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)) {
if (Kind.isMergeableConst4())
return SmallROData4Section;
if (Kind.isMergeableConst8())
diff --git a/llvm/test/CodeGen/RISCV/calls.ll b/llvm/test/CodeGen/RISCV/calls.ll
index 58b10cf53971f2..598a026fb95526 100644
--- a/llvm/test/CodeGen/RISCV/calls.ll
+++ b/llvm/test/CodeGen/RISCV/calls.ll
@@ -3,6 +3,14 @@
; RUN: | FileCheck -check-prefixes=CHECK,RV32I %s
; RUN: llc -relocation-model=pic -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=CHECK,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)
@@ -15,6 +23,45 @@ define i32 @test_call_external(i32 %a) nounwind {
; CHECK-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
+; 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
+; 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
+; 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
}
@@ -30,6 +77,45 @@ define i32 @test_call_dso_local(i32 %a) nounwind {
; CHECK-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
}
@@ -39,6 +125,26 @@ define i32 @defined_function(i32 %a) nounwind {
; CHECK: # %bb.0:
; CHECK-NEXT: addi a0, a0, 1
; CHECK-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
}
@@ -52,6 +158,45 @@ define i32 @test_call_defined(i32 %a) nounwind {
; CHECK-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
+; 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
+; 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
+; 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
}
@@ -67,6 +212,50 @@ define i32 @test_call_indirect(ptr %a, i32 %b) nounwind {
; CHECK-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
}
@@ -90,6 +279,74 @@ define i32 @test_call_indirect_no_t0(ptr %a, i32 %b, i32 %c, i32 %d, i32 %e, i32
; CHECK-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
}
@@ -102,6 +359,26 @@ define fastcc i32 @fastcc_function(i32 %a, i32 %b) nounwind {
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-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
}
@@ -119,6 +396,62 @@ define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind {
; CHECK-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
+; 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
+; 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
+; 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
}
@@ -147,6 +480,98 @@ define i32 @test_call_external_many_args(i32 %a) nounwind {
; CHECK-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
+; 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
+; 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
+; 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
@@ -158,6 +583,30 @@ define i32 @defined_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 %
; CHECK-NEXT: lw a0, 4(sp)
; CHECK-NEXT: addi a0, a0, 1
; CHECK-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
}
@@ -180,6 +629,81 @@ define i32 @test_call_defined_many_args(i32 %a) nounwind {
; CHECK-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 16
; CHECK-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
+; 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
+; 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
+; 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..ad81db75f7bc97 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(.Ltmp0)
+; RV64I-LARGE-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi2)
+; 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 62b1549a5d58ad..4d4580188096f0 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
@@ -7,6 +7,8 @@
; RUN: | FileCheck -check-prefix=RV64I %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs -code-model=medium < %s \
; RUN: | FileCheck -check-prefix=RV64I-MEDIUM %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs -code-model=large < %s \
+; RUN: | 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,15 @@ 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(.Ltmp0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi12)(a0)
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
label:
@@ -531,6 +640,15 @@ 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(.Ltmp1+8)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi13)(a0)
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
label:
@@ -575,6 +693,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 +735,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 +769,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 +803,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 +837,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 +877,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 +1093,47 @@ define i64 @fold_addi_from_
diff erent_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_
diff erent_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
@@ -1006,6 +1202,19 @@ define i32 @crash() {
; RV64I-MEDIUM-NEXT: sw a0, 0(zero)
; RV64I-MEDIUM-NEXT: li a0, 0
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: crash:
+; RV64I-LARGE: # %bb.0: # %entry
+; RV64I-LARGE-NEXT: li a0, 1
+; RV64I-LARGE-NEXT: .Lpcrel_hi15:
+; RV64I-LARGE-NEXT: auipc a1, %pcrel_hi(.LCPI21_0)
+; RV64I-LARGE-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi15)(a1)
+; RV64I-LARGE-NEXT: add a0, a1, a0
+; RV64I-LARGE-NEXT: lbu a0, 400(a0)
+; RV64I-LARGE-NEXT: seqz a0, a0
+; RV64I-LARGE-NEXT: sw a0, 0(zero)
+; RV64I-LARGE-NEXT: li a0, 0
+; RV64I-LARGE-NEXT: ret
entry:
%idxprom7.peel = sext i32 1 to i64
br label %for.inc.peel
diff --git a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll
index 7fae0ca692669e..2a652f5af1e4ea 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,RV32I-MEDIUM-NO-INTEGRATED %s
; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM,RV64I-MEDIUM-NO-INTEGRATED %s
+; RUN: llc -mtriple=riscv64 -code-model=large -verify-machineinstrs -no-integrated-as < %s \
+; RUN: | FileCheck -check-prefixes=RV64I-LARGE,RV64I-LARGE-NO-INTEGRATED %s
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV32I,RV32I-INTEGRATED %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
@@ -15,6 +17,8 @@
; RUN: | FileCheck -check-prefixes=RV32I-MEDIUM,RV32I-MEDIUM-INTEGRATED %s
; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM,RV64I-MEDIUM-INTEGRATED %s
+; RUN: llc -mtriple=riscv64 -code-model=large -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV64I-LARGE,RV64I-LARGE-INTEGRATED %s
@eg = external global [4000 x i32], align 4
@ewg = extern_weak global [4000 x i32], align 4
@@ -43,6 +47,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
}
@@ -75,6 +85,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
}
@@ -107,6 +124,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
@@ -146,6 +170,16 @@ define void @constraint_m_with_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi0)(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
}
@@ -184,6 +218,16 @@ define void @constraint_m_with_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi1)(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
}
@@ -222,6 +266,19 @@ define void @constraint_m_with_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi2)(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
}
@@ -262,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
}
@@ -302,6 +369,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
}
@@ -348,6 +425,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
}
@@ -394,6 +484,17 @@ define void @constraint_m_with_local_1() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi6)(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(.Ltmp0)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi6)(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -444,6 +545,17 @@ define void @constraint_m_with_local_2() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi7)(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(.Ltmp1+4)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi7)(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -494,6 +606,17 @@ define void @constraint_m_with_local_3() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi8)(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(.Ltmp2+2000)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi8)(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -537,6 +660,16 @@ define void @constraint_m_with_multi_operands() nounwind {
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: #NO_APP
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
;
+; RV64I-LARGE-NO-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV64I-LARGE-NO-INTEGRATED: # %bb.0:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .Lpcrel_hi9:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: auipc a0, %pcrel_hi(.LCPI12_0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a0); sw zero, 0(a0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+;
; RV32I-INTEGRATED-LABEL: constraint_m_with_multi_operands:
; RV32I-INTEGRATED: # %bb.0:
; RV32I-INTEGRATED-NEXT: lui a0, %hi(eg)
@@ -574,6 +707,17 @@ define void @constraint_m_with_multi_operands() nounwind {
; RV64I-MEDIUM-INTEGRATED-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
; RV64I-MEDIUM-INTEGRATED-NEXT: #NO_APP
; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-LARGE-INTEGRATED-LABEL: constraint_m_with_multi_operands:
+; RV64I-LARGE-INTEGRATED: # %bb.0:
+; RV64I-LARGE-INTEGRATED-NEXT: .Lpcrel_hi9:
+; RV64I-LARGE-INTEGRATED-NEXT: auipc a0, %pcrel_hi(.LCPI12_0)
+; RV64I-LARGE-INTEGRATED-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi9)(a0)
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a0)
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: ret
call void asm "sw zero, $0; sw zero, $1", "=*m,=*m"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
ret void
}
@@ -624,6 +768,19 @@ define void @constraint_m_with_multi_asm() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi10)(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
@@ -692,6 +849,23 @@ define i32 @constraint_m_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
;
+; RV64I-LARGE-NO-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV64I-LARGE-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .Lpcrel_hi11:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI14_0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi11)(a1)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB14_2
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+;
; RV32I-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
; RV32I-INTEGRATED: # %bb.0: # %entry
; RV32I-INTEGRATED-NEXT: lui a1, %hi(eg)
@@ -761,6 +935,25 @@ define i32 @constraint_m_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-INTEGRATED-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-LARGE-INTEGRATED-LABEL: constraint_m_with_callbr_multi_operands:
+; RV64I-LARGE-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-INTEGRATED-NEXT: .Lpcrel_hi11:
+; RV64I-LARGE-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI14_0)
+; RV64I-LARGE-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi11)(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB14_2
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-INTEGRATED-NEXT: ret
+; RV64I-LARGE-INTEGRATED-NEXT: .LBB14_2: # Block address taken
+; RV64I-LARGE-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-INTEGRATED-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]
@@ -850,6 +1043,27 @@ define i32 @constraint_m_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
;
+; RV64I-LARGE-NO-INTEGRATED-LABEL: constraint_m_with_multi_callbr_asm:
+; RV64I-LARGE-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .Lpcrel_hi12:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI15_0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi12)(a1)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); beqz a0, .LBB15_3
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); beqz a0, .LBB15_3
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .LBB15_3: # Block address taken
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+;
; RV32I-INTEGRATED-LABEL: constraint_m_with_multi_callbr_asm:
; RV32I-INTEGRATED: # %bb.0: # %entry
; RV32I-INTEGRATED-NEXT: lui a1, %hi(eg)
@@ -935,6 +1149,29 @@ define i32 @constraint_m_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-INTEGRATED-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-LARGE-INTEGRATED-LABEL: constraint_m_with_multi_callbr_asm:
+; RV64I-LARGE-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-INTEGRATED-NEXT: .Lpcrel_hi12:
+; RV64I-LARGE-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI15_0)
+; RV64I-LARGE-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi12)(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB15_3
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB15_3
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-INTEGRATED-NEXT: ret
+; RV64I-LARGE-INTEGRATED-NEXT: .LBB15_3: # Block address taken
+; RV64I-LARGE-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-INTEGRATED-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]
@@ -972,6 +1209,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
}
@@ -1004,6 +1247,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
}
@@ -1036,6 +1286,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
@@ -1075,6 +1332,16 @@ define void @constraint_o_with_global_1() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi13)(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
}
@@ -1113,6 +1380,16 @@ define void @constraint_o_with_global_2() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi14)(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
}
@@ -1151,6 +1428,19 @@ define void @constraint_o_with_global_3() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi15)(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
}
@@ -1191,6 +1481,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
}
@@ -1231,6 +1531,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
}
@@ -1277,6 +1587,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
}
@@ -1327,6 +1650,19 @@ define void @constraint_o_with_multi_asm() nounwind {
; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi19)(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_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)
+; 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
@@ -1395,6 +1731,23 @@ define i32 @constraint_o_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
;
+; RV64I-LARGE-NO-INTEGRATED-LABEL: constraint_o_with_callbr_multi_operands:
+; RV64I-LARGE-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .Lpcrel_hi20:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI26_0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi20)(a1)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB26_2
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .LBB26_2: # Block address taken
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+;
; RV32I-INTEGRATED-LABEL: constraint_o_with_callbr_multi_operands:
; RV32I-INTEGRATED: # %bb.0: # %entry
; RV32I-INTEGRATED-NEXT: lui a1, %hi(eg)
@@ -1464,6 +1817,25 @@ define i32 @constraint_o_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-INTEGRATED-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-LARGE-INTEGRATED-LABEL: constraint_o_with_callbr_multi_operands:
+; RV64I-LARGE-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-INTEGRATED-NEXT: .Lpcrel_hi20:
+; RV64I-LARGE-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI26_0)
+; RV64I-LARGE-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi20)(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB26_2
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-INTEGRATED-NEXT: ret
+; RV64I-LARGE-INTEGRATED-NEXT: .LBB26_2: # Block address taken
+; RV64I-LARGE-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-INTEGRATED-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]
@@ -1553,6 +1925,27 @@ define i32 @constraint_o_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
;
+; RV64I-LARGE-NO-INTEGRATED-LABEL: constraint_o_with_multi_callbr_asm:
+; RV64I-LARGE-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .Lpcrel_hi21:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI27_0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi21)(a1)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); beqz a0, .LBB27_3
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); beqz a0, .LBB27_3
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .LBB27_3: # Block address taken
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+;
; RV32I-INTEGRATED-LABEL: constraint_o_with_multi_callbr_asm:
; RV32I-INTEGRATED: # %bb.0: # %entry
; RV32I-INTEGRATED-NEXT: lui a1, %hi(eg)
@@ -1638,6 +2031,29 @@ define i32 @constraint_o_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-INTEGRATED-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-LARGE-INTEGRATED-LABEL: constraint_o_with_multi_callbr_asm:
+; RV64I-LARGE-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-INTEGRATED-NEXT: .Lpcrel_hi21:
+; RV64I-LARGE-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI27_0)
+; RV64I-LARGE-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi21)(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB27_3
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB27_3
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-INTEGRATED-NEXT: ret
+; RV64I-LARGE-INTEGRATED-NEXT: .LBB27_3: # Block address taken
+; RV64I-LARGE-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-INTEGRATED-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]
@@ -1693,6 +2109,17 @@ define void @constraint_o_with_local_1() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi22)(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_hi22:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.Ltmp3)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi22)(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -1743,6 +2170,17 @@ define void @constraint_o_with_local_2() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi23)(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_hi23:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.Ltmp4+4)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi23)(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -1793,6 +2231,17 @@ define void @constraint_o_with_local_3() nounwind {
; RV64I-MEDIUM-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi24)(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_hi24:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.Ltmp5+2000)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, %pcrel_lo(.Lpcrel_hi24)(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -1841,6 +2290,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
@@ -1878,6 +2337,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
@@ -1921,6 +2388,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_hi25:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI33_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi25)(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
}
@@ -1963,6 +2440,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_hi26:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI34_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi26)(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
}
@@ -2005,6 +2493,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_hi27:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI35_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi27)(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
}
@@ -2047,6 +2548,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_hi28:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI36_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi28)(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
}
@@ -2091,6 +2602,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_hi29:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI37_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi29)(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
}
@@ -2139,6 +2661,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_hi30:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI38_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi30)(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
}
@@ -2193,6 +2728,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_hi31:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.LCPI39_0)
+; RV64I-LARGE-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi31)(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
@@ -2265,6 +2813,23 @@ define i32 @constraint_A_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
;
+; RV64I-LARGE-NO-INTEGRATED-LABEL: constraint_A_with_callbr_multi_operands:
+; RV64I-LARGE-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .Lpcrel_hi32:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI40_0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi32)(a1)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB40_2
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .LBB40_2: # Block address taken
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+;
; RV32I-INTEGRATED-LABEL: constraint_A_with_callbr_multi_operands:
; RV32I-INTEGRATED: # %bb.0: # %entry
; RV32I-INTEGRATED-NEXT: lui a1, %hi(eg)
@@ -2338,6 +2903,25 @@ define i32 @constraint_A_with_callbr_multi_operands(i32 %a) {
; RV64I-MEDIUM-INTEGRATED-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-LARGE-INTEGRATED-LABEL: constraint_A_with_callbr_multi_operands:
+; RV64I-LARGE-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-INTEGRATED-NEXT: .Lpcrel_hi32:
+; RV64I-LARGE-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI40_0)
+; RV64I-LARGE-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi32)(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB40_2
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.1: # %normal
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-INTEGRATED-NEXT: ret
+; RV64I-LARGE-INTEGRATED-NEXT: .LBB40_2: # Block address taken
+; RV64I-LARGE-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-INTEGRATED-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]
@@ -2431,6 +3015,27 @@ define i32 @constraint_A_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-NO-INTEGRATED-NEXT: ret
;
+; RV64I-LARGE-NO-INTEGRATED-LABEL: constraint_A_with_multi_callbr_asm:
+; RV64I-LARGE-NO-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .Lpcrel_hi33:
+; RV64I-LARGE-NO-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI41_0)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi33)(a1)
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); beqz a0, .LBB41_3
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: sw zero, 0(a1); beqz a0, .LBB41_3
+; RV64I-LARGE-NO-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+; RV64I-LARGE-NO-INTEGRATED-NEXT: .LBB41_3: # Block address taken
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-NO-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-NO-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-NO-INTEGRATED-NEXT: ret
+;
; RV32I-INTEGRATED-LABEL: constraint_A_with_multi_callbr_asm:
; RV32I-INTEGRATED: # %bb.0: # %entry
; RV32I-INTEGRATED-NEXT: lui a1, %hi(eg)
@@ -2520,6 +3125,29 @@ define i32 @constraint_A_with_multi_callbr_asm(i32 %a) {
; RV64I-MEDIUM-INTEGRATED-NEXT: # Label of block must be emitted
; RV64I-MEDIUM-INTEGRATED-NEXT: li a0, 1
; RV64I-MEDIUM-INTEGRATED-NEXT: ret
+;
+; RV64I-LARGE-INTEGRATED-LABEL: constraint_A_with_multi_callbr_asm:
+; RV64I-LARGE-INTEGRATED: # %bb.0: # %entry
+; RV64I-LARGE-INTEGRATED-NEXT: .Lpcrel_hi33:
+; RV64I-LARGE-INTEGRATED-NEXT: auipc a1, %pcrel_hi(.LCPI41_0)
+; RV64I-LARGE-INTEGRATED-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi33)(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB41_3
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.1: # %normal0
+; RV64I-LARGE-INTEGRATED-NEXT: #APP
+; RV64I-LARGE-INTEGRATED-NEXT: sw zero, 0(a1)
+; RV64I-LARGE-INTEGRATED-NEXT: beqz a0, .LBB41_3
+; RV64I-LARGE-INTEGRATED-NEXT: #NO_APP
+; RV64I-LARGE-INTEGRATED-NEXT: # %bb.2: # %normal1
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 0
+; RV64I-LARGE-INTEGRATED-NEXT: ret
+; RV64I-LARGE-INTEGRATED-NEXT: .LBB41_3: # Block address taken
+; RV64I-LARGE-INTEGRATED-NEXT: # %fail
+; RV64I-LARGE-INTEGRATED-NEXT: # Label of block must be emitted
+; RV64I-LARGE-INTEGRATED-NEXT: li a0, 1
+; RV64I-LARGE-INTEGRATED-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]
@@ -2579,6 +3207,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_hi34:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.Ltmp6)
+; RV64I-LARGE-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi34)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -2633,6 +3273,18 @@ 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_hi35:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.Ltmp7+4)
+; RV64I-LARGE-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi35)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -2687,6 +3339,18 @@ 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_hi36:
+; RV64I-LARGE-NEXT: auipc a0, %pcrel_hi(.Ltmp8+2000)
+; RV64I-LARGE-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi36)
+; RV64I-LARGE-NEXT: #APP
+; RV64I-LARGE-NEXT: lw zero, 0(a0)
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
entry:
br label %label
@@ -2740,6 +3404,17 @@ define void @should_not_fold() {
; RV64I-MEDIUM-NEXT: ecall
; RV64I-MEDIUM-NEXT: #NO_APP
; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: should_not_fold:
+; RV64I-LARGE: # %bb.0: # %start
+; RV64I-LARGE-NEXT: .cfi_def_cfa_offset 0
+; 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: #APP
+; RV64I-LARGE-NEXT: ecall
+; RV64I-LARGE-NEXT: #NO_APP
+; RV64I-LARGE-NEXT: ret
start:
%0 = tail call ptr asm sideeffect alignstack "ecall", "=&{x10},0,~{vtype},~{vl},~{vxsat},~{vxrm},~{memory}"(ptr @_ZN5repro9MY_BUFFER17hb0f674501d5980a6E)
ret void
More information about the llvm-commits
mailing list