diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/Lanai/LanaiISelLowering.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp | 14 | ||||
-rw-r--r-- | llvm/test/CodeGen/Lanai/codemodel.ll | 14 |
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 +} |