diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 77a997588c4fe..cbaabe521002a 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -3189,12 +3189,16 @@ bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(unsigned Width, SDNode *N) const { if (!GA) return false; - std::optional CR = GA->getGlobal()->getAbsoluteSymbolRange(); - if (!CR) - return Width == 32 && TM.getCodeModel() == CodeModel::Small; - - return CR->getSignedMin().sge(-1ull << Width) && - CR->getSignedMax().slt(1ull << Width); + auto *GV = GA->getGlobal(); + std::optional CR = GV->getAbsoluteSymbolRange(); + if (CR) + return CR->getSignedMin().sge(-1ull << Width) && + CR->getSignedMax().slt(1ull << Width); + // In the kernel code model, globals are in the negative 2GB of the address + // space, so globals can be a sign extended 32-bit immediate. + // In other code models, small globals are in the low 2GB of the address + // space, so sign extending them is equivalent to zero extending them. + return Width == 32 && !TM.isLargeGlobalValue(GV); } X86::CondCode X86DAGToDAGISel::getCondFromNode(SDNode *N) const { diff --git a/llvm/test/CodeGen/X86/relocimm-small-model.ll b/llvm/test/CodeGen/X86/relocimm-code-model.ll similarity index 62% rename from llvm/test/CodeGen/X86/relocimm-small-model.ll rename to llvm/test/CodeGen/X86/relocimm-code-model.ll index 5c128e15c1e26..82483abc1ed0a 100644 --- a/llvm/test/CodeGen/X86/relocimm-small-model.ll +++ b/llvm/test/CodeGen/X86/relocimm-code-model.ll @@ -1,5 +1,9 @@ ; RUN: llc < %s | FileCheck %s --check-prefix=CHECK-SMALL -; RUN: llc --code-model=medium < %s | FileCheck %s --check-prefix=CHECK-MEDIUM +; RUN: llc --code-model=medium -large-data-threshold=100 < %s | FileCheck %s --check-prefix=CHECK-SMALL +; RUN: llc --code-model=medium < %s | FileCheck %s --check-prefix=CHECK-LARGE +; RUN: llc --code-model=large -large-data-threshold=100 < %s | FileCheck %s --check-prefix=CHECK-SMALL +; RUN: llc --code-model=large < %s | FileCheck %s --check-prefix=CHECK-LARGE +; RUN: llc --code-model=kernel < %s | FileCheck %s --check-prefix=CHECK-SMALL target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -9,7 +13,7 @@ target triple = "x86_64-unknown-linux-gnu" declare void @f() define void @foo(i64 %b) { -; CHECK-MEDIUM: cmpq %rax, %rdi +; CHECK-LARGE: cmpq %rax, %rdi ; CHECK-SMALL: cmpq $a, %rdi entry: %cmp = icmp eq i64 %b, ptrtoint (ptr @a to i64)