Skip to content

Commit

Permalink
[X86] Allow accessing large globals in small code model (#74785)
Browse files Browse the repository at this point in the history
This removes some assumptions that the small code model will only
reference "near" globals.

There are still some missing optimizations and wrong code sequences, but
I'd like to address those separately. This will require auditing any
checks of the code model in the X86 backend.
  • Loading branch information
aeubanks committed Dec 8, 2023
1 parent 2b36d85 commit 687e63a
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 44 deletions.
31 changes: 9 additions & 22 deletions llvm/lib/Target/X86/X86InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8717,11 +8717,6 @@ bool X86InstrInfo::isSafeToMoveRegClassDefs(
/// TODO: Eliminate this and move the code to X86MachineFunctionInfo.
///
unsigned X86InstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
assert((!Subtarget.is64Bit() ||
MF->getTarget().getCodeModel() == CodeModel::Medium ||
MF->getTarget().getCodeModel() == CodeModel::Large) &&
"X86-64 PIC uses RIP relative addressing");

X86MachineFunctionInfo *X86FI = MF->getInfo<X86MachineFunctionInfo>();
Register GlobalBaseReg = X86FI->getGlobalBaseReg();
if (GlobalBaseReg != 0)
Expand Down Expand Up @@ -10083,12 +10078,6 @@ struct CGBR : public MachineFunctionPass {
static_cast<const X86TargetMachine *>(&MF.getTarget());
const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();

// Don't do anything in the 64-bit small and kernel code models. They use
// RIP-relative addressing for everything.
if (STI.is64Bit() && (TM->getCodeModel() == CodeModel::Small ||
TM->getCodeModel() == CodeModel::Kernel))
return false;

// Only emit a global base reg in PIC mode.
if (!TM->isPositionIndependent())
return false;
Expand All @@ -10114,16 +10103,7 @@ struct CGBR : public MachineFunctionPass {
PC = GlobalBaseReg;

if (STI.is64Bit()) {
if (TM->getCodeModel() == CodeModel::Medium) {
// In the medium code model, use a RIP-relative LEA to materialize the
// GOT.
BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PC)
.addReg(X86::RIP)
.addImm(0)
.addReg(0)
.addExternalSymbol("_GLOBAL_OFFSET_TABLE_")
.addReg(0);
} else if (TM->getCodeModel() == CodeModel::Large) {
if (TM->getCodeModel() == CodeModel::Large) {
// In the large code model, we are aiming for this code, though the
// register allocation may vary:
// leaq .LN$pb(%rip), %rax
Expand All @@ -10146,7 +10126,14 @@ struct CGBR : public MachineFunctionPass {
.addReg(PBReg, RegState::Kill)
.addReg(GOTReg, RegState::Kill);
} else {
llvm_unreachable("unexpected code model");
// In other code models, use a RIP-relative LEA to materialize the
// GOT.
BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PC)
.addReg(X86::RIP)
.addImm(0)
.addReg(0)
.addExternalSymbol("_GLOBAL_OFFSET_TABLE_")
.addReg(0);
}
} else {
// Operand of MovePCtoStack is completely ignored by asm printer. It's
Expand Down
238 changes: 216 additions & 22 deletions llvm/test/CodeGen/X86/code-model-elf.ll
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ target triple = "x86_64--linux"
@extern_data = external global [10 x i32], align 16
@thread_data = external thread_local global i32, align 4
@unknown_size_data = dso_local global [0 x i32] zeroinitializer, align 16

@forced_small_data = dso_local global [10 x i32] zeroinitializer, code_model "small", align 16
@forced_large_data = dso_local global [10 x i32] zeroinitializer, code_model "large", align 16

define dso_local ptr @lea_static_data() #0 {
; SMALL-STATIC-LABEL: lea_static_data:
Expand Down Expand Up @@ -223,6 +224,199 @@ define dso_local ptr @lea_unknown_size_data() #0 {
ret ptr @unknown_size_data
}

; TODO: make nopic small and medium instruction sequence the same
define dso_local ptr @lea_forced_small_data() #0 {
; SMALL-STATIC-LABEL: lea_forced_small_data:
; SMALL-STATIC: # %bb.0:
; SMALL-STATIC-NEXT: movl $forced_small_data, %eax
; SMALL-STATIC-NEXT: retq
;
; MEDIUM-STATIC-LABEL: lea_forced_small_data:
; MEDIUM-STATIC: # %bb.0:
; MEDIUM-STATIC-NEXT: movabsq $forced_small_data, %rax
; MEDIUM-STATIC-NEXT: retq
;
; LARGE-STATIC-LABEL: lea_forced_small_data:
; LARGE-STATIC: # %bb.0:
; LARGE-STATIC-NEXT: movabsq $forced_small_data, %rax
; LARGE-STATIC-NEXT: retq
;
; SMALL-PIC-LABEL: lea_forced_small_data:
; SMALL-PIC: # %bb.0:
; SMALL-PIC-NEXT: leaq forced_small_data(%rip), %rax
; SMALL-PIC-NEXT: retq
;
; MEDIUM-SMALL-DATA-PIC-LABEL: lea_forced_small_data:
; MEDIUM-SMALL-DATA-PIC: # %bb.0:
; MEDIUM-SMALL-DATA-PIC-NEXT: leaq forced_small_data(%rip), %rax
; MEDIUM-SMALL-DATA-PIC-NEXT: retq
;
; MEDIUM-PIC-LABEL: lea_forced_small_data:
; MEDIUM-PIC: # %bb.0:
; MEDIUM-PIC-NEXT: leaq forced_small_data(%rip), %rax
; MEDIUM-PIC-NEXT: retq
;
; LARGE-PIC-LABEL: lea_forced_small_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L4$pb:
; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $forced_small_data@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
; LARGE-PIC-NEXT: retq
ret ptr @forced_small_data
}

; TODO: make small and medium instruction sequence the same
define dso_local i32 @load_forced_small_data() #0 {
; SMALL-STATIC-LABEL: load_forced_small_data:
; SMALL-STATIC: # %bb.0:
; SMALL-STATIC-NEXT: movl forced_small_data+8(%rip), %eax
; SMALL-STATIC-NEXT: retq
;
; MEDIUM-STATIC-LABEL: load_forced_small_data:
; MEDIUM-STATIC: # %bb.0:
; MEDIUM-STATIC-NEXT: movabsq $forced_small_data, %rax
; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
; MEDIUM-STATIC-NEXT: retq
;
; LARGE-STATIC-LABEL: load_forced_small_data:
; LARGE-STATIC: # %bb.0:
; LARGE-STATIC-NEXT: movabsq $forced_small_data, %rax
; LARGE-STATIC-NEXT: movl 8(%rax), %eax
; LARGE-STATIC-NEXT: retq
;
; SMALL-PIC-LABEL: load_forced_small_data:
; SMALL-PIC: # %bb.0:
; SMALL-PIC-NEXT: movl forced_small_data+8(%rip), %eax
; SMALL-PIC-NEXT: retq
;
; MEDIUM-SMALL-DATA-PIC-LABEL: load_forced_small_data:
; MEDIUM-SMALL-DATA-PIC: # %bb.0:
; MEDIUM-SMALL-DATA-PIC-NEXT: leaq forced_small_data(%rip), %rax
; MEDIUM-SMALL-DATA-PIC-NEXT: movl 8(%rax), %eax
; MEDIUM-SMALL-DATA-PIC-NEXT: retq
;
; MEDIUM-PIC-LABEL: load_forced_small_data:
; MEDIUM-PIC: # %bb.0:
; MEDIUM-PIC-NEXT: leaq forced_small_data(%rip), %rax
; MEDIUM-PIC-NEXT: movl 8(%rax), %eax
; MEDIUM-PIC-NEXT: retq
;
; LARGE-PIC-LABEL: load_forced_small_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L5$pb:
; LARGE-PIC-NEXT: leaq .L5$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $forced_small_data@GOTOFF, %rax
; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax
; LARGE-PIC-NEXT: retq
%rv = load i32, ptr getelementptr inbounds (i32, ptr @forced_small_data, i64 2)
ret i32 %rv
}

; TODO: fix small code model instruction sequences to use 64-bit constants
define dso_local ptr @lea_forced_large_data() #0 {
; SMALL-STATIC-LABEL: lea_forced_large_data:
; SMALL-STATIC: # %bb.0:
; SMALL-STATIC-NEXT: movl $forced_large_data, %eax
; SMALL-STATIC-NEXT: retq
;
; MEDIUM-STATIC-LABEL: lea_forced_large_data:
; MEDIUM-STATIC: # %bb.0:
; MEDIUM-STATIC-NEXT: movabsq $forced_large_data, %rax
; MEDIUM-STATIC-NEXT: retq
;
; LARGE-STATIC-LABEL: lea_forced_large_data:
; LARGE-STATIC: # %bb.0:
; LARGE-STATIC-NEXT: movabsq $forced_large_data, %rax
; LARGE-STATIC-NEXT: retq
;
; SMALL-PIC-LABEL: lea_forced_large_data:
; SMALL-PIC: # %bb.0:
; SMALL-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
; SMALL-PIC-NEXT: leaq forced_large_data@GOTOFF(%rax), %rax
; SMALL-PIC-NEXT: retq
;
; MEDIUM-SMALL-DATA-PIC-LABEL: lea_forced_large_data:
; MEDIUM-SMALL-DATA-PIC: # %bb.0:
; MEDIUM-SMALL-DATA-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
; MEDIUM-SMALL-DATA-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rax
; MEDIUM-SMALL-DATA-PIC-NEXT: addq %rcx, %rax
; MEDIUM-SMALL-DATA-PIC-NEXT: retq
;
; MEDIUM-PIC-LABEL: lea_forced_large_data:
; MEDIUM-PIC: # %bb.0:
; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
; MEDIUM-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rax
; MEDIUM-PIC-NEXT: addq %rcx, %rax
; MEDIUM-PIC-NEXT: retq
;
; LARGE-PIC-LABEL: lea_forced_large_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L6$pb:
; LARGE-PIC-NEXT: leaq .L6$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
; LARGE-PIC-NEXT: retq
ret ptr @forced_large_data
}

define dso_local i32 @load_forced_large_data() #0 {
; SMALL-STATIC-LABEL: load_forced_large_data:
; SMALL-STATIC: # %bb.0:
; SMALL-STATIC-NEXT: movl forced_large_data+8(%rip), %eax
; SMALL-STATIC-NEXT: retq
;
; MEDIUM-STATIC-LABEL: load_forced_large_data:
; MEDIUM-STATIC: # %bb.0:
; MEDIUM-STATIC-NEXT: movabsq $forced_large_data, %rax
; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
; MEDIUM-STATIC-NEXT: retq
;
; LARGE-STATIC-LABEL: load_forced_large_data:
; LARGE-STATIC: # %bb.0:
; LARGE-STATIC-NEXT: movabsq $forced_large_data, %rax
; LARGE-STATIC-NEXT: movl 8(%rax), %eax
; LARGE-STATIC-NEXT: retq
;
; SMALL-PIC-LABEL: load_forced_large_data:
; SMALL-PIC: # %bb.0:
; SMALL-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
; SMALL-PIC-NEXT: movl forced_large_data@GOTOFF+8(%rax), %eax
; SMALL-PIC-NEXT: retq
;
; MEDIUM-SMALL-DATA-PIC-LABEL: load_forced_large_data:
; MEDIUM-SMALL-DATA-PIC: # %bb.0:
; MEDIUM-SMALL-DATA-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
; MEDIUM-SMALL-DATA-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rcx
; MEDIUM-SMALL-DATA-PIC-NEXT: movl 8(%rax,%rcx), %eax
; MEDIUM-SMALL-DATA-PIC-NEXT: retq
;
; MEDIUM-PIC-LABEL: load_forced_large_data:
; MEDIUM-PIC: # %bb.0:
; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
; MEDIUM-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rcx
; MEDIUM-PIC-NEXT: movl 8(%rax,%rcx), %eax
; MEDIUM-PIC-NEXT: retq
;
; LARGE-PIC-LABEL: load_forced_large_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L7$pb:
; LARGE-PIC-NEXT: leaq .L7$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rax
; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax
; LARGE-PIC-NEXT: retq
%rv = load i32, ptr getelementptr inbounds (i32, ptr @forced_large_data, i64 2)
ret i32 %rv
}

define dso_local i32 @load_global_data() #0 {
; SMALL-STATIC-LABEL: load_global_data:
; SMALL-STATIC: # %bb.0:
Expand Down Expand Up @@ -261,9 +455,9 @@ define dso_local i32 @load_global_data() #0 {
;
; LARGE-PIC-LABEL: load_global_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L4$pb:
; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx
; LARGE-PIC-NEXT: .L8$pb:
; LARGE-PIC-NEXT: leaq .L8$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L8$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax
Expand Down Expand Up @@ -311,9 +505,9 @@ define dso_local i32 @load_extern_data() #0 {
;
; LARGE-PIC-LABEL: load_extern_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L5$pb:
; LARGE-PIC-NEXT: leaq .L5$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx
; LARGE-PIC-NEXT: .L9$pb:
; LARGE-PIC-NEXT: leaq .L9$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax
; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
Expand Down Expand Up @@ -362,9 +556,9 @@ define dso_local i32 @load_unknown_size_data() #0 {
;
; LARGE-PIC-LABEL: load_unknown_size_data:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L6$pb:
; LARGE-PIC-NEXT: leaq .L6$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx
; LARGE-PIC-NEXT: .L10$pb:
; LARGE-PIC-NEXT: leaq .L10$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $unknown_size_data@GOTOFF, %rax
; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax
Expand Down Expand Up @@ -422,9 +616,9 @@ define dso_local ptr @lea_static_fn() #0 {
;
; LARGE-PIC-LABEL: lea_static_fn:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L9$pb:
; LARGE-PIC-NEXT: leaq .L9$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx
; LARGE-PIC-NEXT: .L13$pb:
; LARGE-PIC-NEXT: leaq .L13$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L13$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $static_fn@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
Expand Down Expand Up @@ -465,9 +659,9 @@ define dso_local ptr @lea_global_fn() #0 {
;
; LARGE-PIC-LABEL: lea_global_fn:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L10$pb:
; LARGE-PIC-NEXT: leaq .L10$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx
; LARGE-PIC-NEXT: .L14$pb:
; LARGE-PIC-NEXT: leaq .L14$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L14$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $global_fn@GOTOFF, %rax
; LARGE-PIC-NEXT: addq %rcx, %rax
Expand Down Expand Up @@ -508,9 +702,9 @@ define dso_local ptr @lea_extern_fn() #0 {
;
; LARGE-PIC-LABEL: lea_extern_fn:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L11$pb:
; LARGE-PIC-NEXT: leaq .L11$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L11$pb, %rcx
; LARGE-PIC-NEXT: .L15$pb:
; LARGE-PIC-NEXT: leaq .L15$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L15$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rax
; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
Expand Down Expand Up @@ -586,9 +780,9 @@ define dso_local float @load_constant_pool(float %x) #0 {
;
; LARGE-PIC-LABEL: load_constant_pool:
; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L13$pb:
; LARGE-PIC-NEXT: leaq .L13$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L13$pb, %rcx
; LARGE-PIC-NEXT: .L17$pb:
; LARGE-PIC-NEXT: leaq .L17$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L17$pb, %rcx
; LARGE-PIC-NEXT: addq %rax, %rcx
; LARGE-PIC-NEXT: movabsq ${{\.?LCPI[0-9]+_[0-9]+}}@GOTOFF, %rax
; LARGE-PIC-NEXT: addss (%rcx,%rax), %xmm0
Expand Down

0 comments on commit 687e63a

Please sign in to comment.