Skip to content

Commit 2366d53

Browse files
authored
[X86] Fix more medium code model addressing modes (#75641)
By looking at whether a global is large instead of looking at the code model. This also fixes references to large data in the small code model. We now always fold any 32-bit offset into the addressing mode with the large code model since it uses 64-bit relocations.
1 parent 7bd1721 commit 2366d53

File tree

5 files changed

+68
-66
lines changed

5 files changed

+68
-66
lines changed

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,9 +1828,7 @@ bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM) {
18281828
// That signifies access to globals that are known to be "near",
18291829
// such as the GOT itself.
18301830
CodeModel::Model M = TM.getCodeModel();
1831-
if (Subtarget->is64Bit() &&
1832-
((M == CodeModel::Large && !IsRIPRelTLS) ||
1833-
(M == CodeModel::Medium && !IsRIPRel)))
1831+
if (Subtarget->is64Bit() && M == CodeModel::Large && !IsRIPRelTLS)
18341832
return true;
18351833

18361834
// Base and index reg must be 0 in order to use %rip as base.
@@ -1866,6 +1864,13 @@ bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM) {
18661864
} else
18671865
llvm_unreachable("Unhandled symbol reference node.");
18681866

1867+
// Can't use an addressing mode with large globals.
1868+
if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1869+
TM.isLargeGlobalValue(AM.GV)) {
1870+
AM = Backup;
1871+
return true;
1872+
}
1873+
18691874
if (foldOffsetIntoAddress(Offset, AM)) {
18701875
AM = Backup;
18711876
return true;
@@ -1910,20 +1915,12 @@ bool X86DAGToDAGISel::matchAddress(SDValue N, X86ISelAddressMode &AM) {
19101915

19111916
// Post-processing: Convert foo to foo(%rip), even in non-PIC mode,
19121917
// because it has a smaller encoding.
1913-
// TODO: Which other code models can use this?
1914-
switch (TM.getCodeModel()) {
1915-
default: break;
1916-
case CodeModel::Small:
1917-
case CodeModel::Kernel:
1918-
if (Subtarget->is64Bit() &&
1919-
AM.Scale == 1 &&
1920-
AM.BaseType == X86ISelAddressMode::RegBase &&
1921-
AM.Base_Reg.getNode() == nullptr &&
1922-
AM.IndexReg.getNode() == nullptr &&
1923-
AM.SymbolFlags == X86II::MO_NO_FLAG &&
1924-
AM.hasSymbolicDisplacement())
1925-
AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
1926-
break;
1918+
if (TM.getCodeModel() != CodeModel::Large &&
1919+
(!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
1920+
AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
1921+
AM.Base_Reg.getNode() == nullptr && AM.IndexReg.getNode() == nullptr &&
1922+
AM.SymbolFlags == X86II::MO_NO_FLAG && AM.hasSymbolicDisplacement()) {
1923+
AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
19271924
}
19281925

19291926
return false;

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2674,34 +2674,33 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
26742674
return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy(DAG.getDataLayout()));
26752675
}
26762676

2677-
bool X86::isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M,
2678-
bool hasSymbolicDisplacement) {
2677+
bool X86::isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model CM,
2678+
bool HasSymbolicDisplacement) {
26792679
// Offset should fit into 32 bit immediate field.
26802680
if (!isInt<32>(Offset))
26812681
return false;
26822682

26832683
// If we don't have a symbolic displacement - we don't have any extra
26842684
// restrictions.
2685-
if (!hasSymbolicDisplacement)
2685+
if (!HasSymbolicDisplacement)
26862686
return true;
26872687

2688-
// FIXME: Some tweaks might be needed for medium code model.
2689-
if (M != CodeModel::Small && M != CodeModel::Kernel)
2690-
return false;
2691-
2692-
// For small code model we assume that latest object is 16MB before end of 31
2693-
// bits boundary. We may also accept pretty large negative constants knowing
2694-
// that all objects are in the positive half of address space.
2695-
if (M == CodeModel::Small && Offset < 16*1024*1024)
2688+
// We can fold large offsets in the large code model because we always use
2689+
// 64-bit offsets.
2690+
if (CM == CodeModel::Large)
26962691
return true;
26972692

26982693
// For kernel code model we know that all object resist in the negative half
26992694
// of 32bits address space. We may not accept negative offsets, since they may
27002695
// be just off and we may accept pretty large positive ones.
2701-
if (M == CodeModel::Kernel && Offset >= 0)
2702-
return true;
2703-
2704-
return false;
2696+
if (CM == CodeModel::Kernel)
2697+
return Offset >= 0;
2698+
2699+
// For other non-large code models we assume that latest small object is 16MB
2700+
// before end of 31 bits boundary. We may also accept pretty large negative
2701+
// constants knowing that all objects are in the positive half of address
2702+
// space.
2703+
return Offset < 16 * 1024 * 1024;
27052704
}
27062705

27072706
/// Return true if the condition is an signed comparison operation.

llvm/test/CodeGen/X86/code-model-elf.ll

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@
1111
; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-PIC
1212
; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large -large-data-threshold=1000 | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-SMALL-DATA-PIC
1313

14+
; Check that the relocations we emit are valid.
15+
; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=small -filetype=obj -o /dev/null
16+
; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=medium -filetype=obj -o /dev/null
17+
; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=large -filetype=obj -o /dev/null
18+
; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=small -filetype=obj -o /dev/null
19+
; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=medium -large-data-threshold=1000 -filetype=obj -o /dev/null
20+
; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=medium -filetype=obj -o /dev/null
21+
; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large -filetype=obj -o /dev/null
22+
; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large -large-data-threshold=1000 -filetype=obj -o /dev/null
23+
1424
; Generated from this C source:
1525
;
1626
; static int static_data[10];
@@ -376,7 +386,6 @@ define dso_local ptr @lea_forced_small_data() #0 {
376386
ret ptr @forced_small_data
377387
}
378388

379-
; TODO: make small and medium instruction sequence the same
380389
define dso_local i32 @load_forced_small_data() #0 {
381390
; SMALL-STATIC-LABEL: load_forced_small_data:
382391
; SMALL-STATIC: # %bb.0:
@@ -385,14 +394,13 @@ define dso_local i32 @load_forced_small_data() #0 {
385394
;
386395
; MEDIUM-STATIC-LABEL: load_forced_small_data:
387396
; MEDIUM-STATIC: # %bb.0:
388-
; MEDIUM-STATIC-NEXT: movl $forced_small_data, %eax
389-
; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
397+
; MEDIUM-STATIC-NEXT: movl forced_small_data+8(%rip), %eax
390398
; MEDIUM-STATIC-NEXT: retq
391399
;
392400
; LARGE-STATIC-LABEL: load_forced_small_data:
393401
; LARGE-STATIC: # %bb.0:
394-
; LARGE-STATIC-NEXT: movl $forced_small_data, %eax
395-
; LARGE-STATIC-NEXT: movl 8(%rax), %eax
402+
; LARGE-STATIC-NEXT: movl $forced_small_data+8, %eax
403+
; LARGE-STATIC-NEXT: movl (%rax), %eax
396404
; LARGE-STATIC-NEXT: retq
397405
;
398406
; SMALL-PIC-LABEL: load_forced_small_data:
@@ -402,14 +410,12 @@ define dso_local i32 @load_forced_small_data() #0 {
402410
;
403411
; MEDIUM-SMALL-DATA-PIC-LABEL: load_forced_small_data:
404412
; MEDIUM-SMALL-DATA-PIC: # %bb.0:
405-
; MEDIUM-SMALL-DATA-PIC-NEXT: leaq forced_small_data(%rip), %rax
406-
; MEDIUM-SMALL-DATA-PIC-NEXT: movl 8(%rax), %eax
413+
; MEDIUM-SMALL-DATA-PIC-NEXT: movl forced_small_data+8(%rip), %eax
407414
; MEDIUM-SMALL-DATA-PIC-NEXT: retq
408415
;
409416
; MEDIUM-PIC-LABEL: load_forced_small_data:
410417
; MEDIUM-PIC: # %bb.0:
411-
; MEDIUM-PIC-NEXT: leaq forced_small_data(%rip), %rax
412-
; MEDIUM-PIC-NEXT: movl 8(%rax), %eax
418+
; MEDIUM-PIC-NEXT: movl forced_small_data+8(%rip), %eax
413419
; MEDIUM-PIC-NEXT: retq
414420
;
415421
; LARGE-PIC-LABEL: load_forced_small_data:
@@ -435,7 +441,6 @@ define dso_local i32 @load_forced_small_data() #0 {
435441
ret i32 %rv
436442
}
437443

438-
; TODO: fix small code model instruction sequences to use 64-bit constants
439444
define dso_local ptr @lea_forced_large_data() #0 {
440445
; SMALL-STATIC-LABEL: lea_forced_large_data:
441446
; SMALL-STATIC: # %bb.0:
@@ -454,8 +459,9 @@ define dso_local ptr @lea_forced_large_data() #0 {
454459
;
455460
; SMALL-PIC-LABEL: lea_forced_large_data:
456461
; SMALL-PIC: # %bb.0:
457-
; SMALL-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
458-
; SMALL-PIC-NEXT: leaq forced_large_data@GOTOFF(%rax), %rax
462+
; SMALL-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
463+
; SMALL-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rax
464+
; SMALL-PIC-NEXT: addq %rcx, %rax
459465
; SMALL-PIC-NEXT: retq
460466
;
461467
; MEDIUM-SMALL-DATA-PIC-LABEL: lea_forced_large_data:
@@ -497,25 +503,27 @@ define dso_local ptr @lea_forced_large_data() #0 {
497503
define dso_local i32 @load_forced_large_data() #0 {
498504
; SMALL-STATIC-LABEL: load_forced_large_data:
499505
; SMALL-STATIC: # %bb.0:
500-
; SMALL-STATIC-NEXT: movl forced_large_data+8(%rip), %eax
506+
; SMALL-STATIC-NEXT: movabsq $forced_large_data+8, %rax
507+
; SMALL-STATIC-NEXT: movl (%rax), %eax
501508
; SMALL-STATIC-NEXT: retq
502509
;
503510
; MEDIUM-STATIC-LABEL: load_forced_large_data:
504511
; MEDIUM-STATIC: # %bb.0:
505-
; MEDIUM-STATIC-NEXT: movabsq $forced_large_data, %rax
506-
; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
512+
; MEDIUM-STATIC-NEXT: movabsq $forced_large_data+8, %rax
513+
; MEDIUM-STATIC-NEXT: movl (%rax), %eax
507514
; MEDIUM-STATIC-NEXT: retq
508515
;
509516
; LARGE-STATIC-LABEL: load_forced_large_data:
510517
; LARGE-STATIC: # %bb.0:
511-
; LARGE-STATIC-NEXT: movabsq $forced_large_data, %rax
512-
; LARGE-STATIC-NEXT: movl 8(%rax), %eax
518+
; LARGE-STATIC-NEXT: movabsq $forced_large_data+8, %rax
519+
; LARGE-STATIC-NEXT: movl (%rax), %eax
513520
; LARGE-STATIC-NEXT: retq
514521
;
515522
; SMALL-PIC-LABEL: load_forced_large_data:
516523
; SMALL-PIC: # %bb.0:
517524
; SMALL-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
518-
; SMALL-PIC-NEXT: movl forced_large_data@GOTOFF+8(%rax), %eax
525+
; SMALL-PIC-NEXT: movabsq $forced_large_data@GOTOFF, %rcx
526+
; SMALL-PIC-NEXT: movl 8(%rax,%rcx), %eax
519527
; SMALL-PIC-NEXT: retq
520528
;
521529
; MEDIUM-SMALL-DATA-PIC-LABEL: load_forced_large_data:
@@ -563,14 +571,14 @@ define dso_local i32 @load_global_data() #0 {
563571
;
564572
; MEDIUM-STATIC-LABEL: load_global_data:
565573
; MEDIUM-STATIC: # %bb.0:
566-
; MEDIUM-STATIC-NEXT: movabsq $global_data, %rax
567-
; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
574+
; MEDIUM-STATIC-NEXT: movabsq $global_data+8, %rax
575+
; MEDIUM-STATIC-NEXT: movl (%rax), %eax
568576
; MEDIUM-STATIC-NEXT: retq
569577
;
570578
; LARGE-STATIC-LABEL: load_global_data:
571579
; LARGE-STATIC: # %bb.0:
572-
; LARGE-STATIC-NEXT: movabsq $global_data, %rax
573-
; LARGE-STATIC-NEXT: movl 8(%rax), %eax
580+
; LARGE-STATIC-NEXT: movabsq $global_data+8, %rax
581+
; LARGE-STATIC-NEXT: movl (%rax), %eax
574582
; LARGE-STATIC-NEXT: retq
575583
;
576584
; SMALL-PIC-LABEL: load_global_data:
@@ -580,8 +588,7 @@ define dso_local i32 @load_global_data() #0 {
580588
;
581589
; MEDIUM-SMALL-DATA-PIC-LABEL: load_global_data:
582590
; MEDIUM-SMALL-DATA-PIC: # %bb.0:
583-
; MEDIUM-SMALL-DATA-PIC-NEXT: leaq global_data(%rip), %rax
584-
; MEDIUM-SMALL-DATA-PIC-NEXT: movl 8(%rax), %eax
591+
; MEDIUM-SMALL-DATA-PIC-NEXT: movl global_data+8(%rip), %eax
585592
; MEDIUM-SMALL-DATA-PIC-NEXT: retq
586593
;
587594
; MEDIUM-PIC-LABEL: load_global_data:
@@ -684,14 +691,14 @@ define dso_local i32 @load_unknown_size_data() #0 {
684691
;
685692
; MEDIUM-STATIC-LABEL: load_unknown_size_data:
686693
; MEDIUM-STATIC: # %bb.0:
687-
; MEDIUM-STATIC-NEXT: movabsq $unknown_size_data, %rax
688-
; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
694+
; MEDIUM-STATIC-NEXT: movabsq $unknown_size_data+8, %rax
695+
; MEDIUM-STATIC-NEXT: movl (%rax), %eax
689696
; MEDIUM-STATIC-NEXT: retq
690697
;
691698
; LARGE-STATIC-LABEL: load_unknown_size_data:
692699
; LARGE-STATIC: # %bb.0:
693-
; LARGE-STATIC-NEXT: movabsq $unknown_size_data, %rax
694-
; LARGE-STATIC-NEXT: movl 8(%rax), %eax
700+
; LARGE-STATIC-NEXT: movabsq $unknown_size_data+8, %rax
701+
; LARGE-STATIC-NEXT: movl (%rax), %eax
695702
; LARGE-STATIC-NEXT: retq
696703
;
697704
; SMALL-PIC-LABEL: load_unknown_size_data:
@@ -1127,8 +1134,7 @@ define dso_local float @load_constant_pool(float %x) #0 {
11271134
;
11281135
; MEDIUM-STATIC-LABEL: load_constant_pool:
11291136
; MEDIUM-STATIC: # %bb.0:
1130-
; MEDIUM-STATIC-NEXT: movl ${{\.?LCPI[0-9]+_[0-9]+}}, %eax
1131-
; MEDIUM-STATIC-NEXT: addss (%rax), %xmm0
1137+
; MEDIUM-STATIC-NEXT: addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
11321138
; MEDIUM-STATIC-NEXT: retq
11331139
;
11341140
; LARGE-STATIC-LABEL: load_constant_pool:

llvm/test/CodeGen/X86/fast-isel-large-object.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
define ptr @f() {
77
; CHECK-LABEL: f:
88
; CHECK: # %bb.0:
9-
; CHECK-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
10-
; CHECK-NEXT: leaq g@GOTOFF(%rax), %rax
9+
; CHECK-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
10+
; CHECK-NEXT: movabsq $g@GOTOFF, %rax
11+
; CHECK-NEXT: addq %rcx, %rax
1112
; CHECK-NEXT: retq
1213
ret ptr @g
1314
}

llvm/test/CodeGen/X86/fold-add.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ define dso_local i64 @one() #0 {
4545
;
4646
; MSTATIC-LABEL: one:
4747
; MSTATIC: # %bb.0: # %entry
48-
; MSTATIC-NEXT: movabsq $foo, %rax
49-
; MSTATIC-NEXT: incq %rax
48+
; MSTATIC-NEXT: movabsq $foo+1, %rax
5049
; MSTATIC-NEXT: retq
5150
;
5251
; MPIC-LABEL: one:

0 commit comments

Comments
 (0)