summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/Lanai/LanaiISelLowering.cpp3
-rw-r--r--llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp14
-rw-r--r--llvm/test/CodeGen/Lanai/codemodel.ll14
3 files changed, 28 insertions, 3 deletions
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
index c5627d21905..ae7870e07d4 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
@@ -1170,8 +1170,7 @@ SDValue LanaiTargetLowering::LowerGlobalAddress(SDValue Op,
// If the code model is small or global variable will be placed in the small
// section, then assume address will fit in 21-bits.
const GlobalObject *GO = GV->getBaseObject();
- if (getTargetMachine().getCodeModel() == CodeModel::Small ||
- (GO && TLOF->isGlobalInSmallSection(GO, getTargetMachine()))) {
+ if (TLOF->isGlobalInSmallSection(GO, getTargetMachine())) {
SDValue Small = DAG.getTargetGlobalAddress(
GV, DL, getPointerTy(DAG.getDataLayout()), Offset, LanaiII::MO_NO_FLAG);
return DAG.getNode(ISD::OR, DL, MVT::i32,
diff --git a/llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp b/llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp
index 4edb4f849da..7475dbd68ae 100644
--- a/llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp
+++ b/llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp
@@ -50,6 +50,9 @@ static bool isInSmallSection(uint64_t Size) {
// section.
bool LanaiTargetObjectFile::isGlobalInSmallSection(
const GlobalObject *GO, const TargetMachine &TM) const {
+ if (GO == nullptr)
+ return false;
+
// We first check the case where global is a declaration, because finding
// section kind using getKindForGlobal() is only allowed for global
// definitions.
@@ -72,12 +75,21 @@ bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,
// section. This method does all the work, except for checking the section
// kind.
bool LanaiTargetObjectFile::isGlobalInSmallSectionImpl(
- const GlobalObject *GO, const TargetMachine & /*TM*/) const {
+ const GlobalObject *GO, const TargetMachine &TM) const {
// Only global variables, not functions.
const auto *GVA = dyn_cast<GlobalVariable>(GO);
if (!GVA)
return false;
+ // Global values placed in sections starting with .ldata do not fit in
+ // 21-bits, so always use large memory access for them. FIXME: This is a
+ // workaround for a tool limitation.
+ if (GVA->getSection().startswith(".ldata"))
+ return false;
+
+ if (TM.getCodeModel() == CodeModel::Small)
+ return true;
+
if (GVA->hasLocalLinkage())
return false;
diff --git a/llvm/test/CodeGen/Lanai/codemodel.ll b/llvm/test/CodeGen/Lanai/codemodel.ll
index e5ec7265924..6bc0dc4d398 100644
--- a/llvm/test/CodeGen/Lanai/codemodel.ll
+++ b/llvm/test/CodeGen/Lanai/codemodel.ll
@@ -28,3 +28,17 @@ entry:
ret i32 %0
}
+@y = local_unnamed_addr global i32* null, section ".ldata,block", align 8
+
+define i32 @foo2() nounwind readonly {
+entry:
+; CHECK-SMALL-LABEL: foo2:
+; CHECK-SMALL: mov hi(y), %r[[REGISTER:[0-9]+]]
+; CHECK-SMALL: or %r[[REGISTER]], lo(y), %r[[REGISTER]]
+; CHECK-LABEL: foo2:
+; CHECK: mov hi(y), %r[[REGISTER:[0-9]+]]
+; CHECK: or %r[[REGISTER]], lo(y), %r[[REGISTER]]
+ %0 = load i32*, i32** @y, align 8
+ %1 = load i32, i32* %0, align 4
+ ret i32 %1
+}
OpenPOWER on IntegriCloud