Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X86] Respect code models more when determining if a global reference can fit in 32 bits #75386

Merged
merged 4 commits into from
Dec 14, 2023

Conversation

aeubanks
Copy link
Contributor

@aeubanks aeubanks commented Dec 13, 2023

For non-GlobalValue references, the small and medium code models can use 32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.
Even the large code model can reference small objects with 32 bit constants as long as we're in no-pic mode, or if the reference is offset from the GOT.

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 13, 2023

@llvm/pr-subscribers-backend-x86

Author: Arthur Eubanks (aeubanks)

Changes

For non-GlobalValue references, the small and medium code models can use 32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.


Patch is 28.66 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/75386.diff

2 Files Affected:

  • (modified) llvm/lib/Target/X86/X86ISelDAGToDAG.cpp (+10-7)
  • (modified) llvm/test/CodeGen/X86/code-model-elf.ll (+174-119)
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 545039b79f1616..363b6c7a4b4ab8 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2940,15 +2940,18 @@ bool X86DAGToDAGISel::selectMOV64Imm32(SDValue N, SDValue &Imm) {
     return false;
 
   Imm = N;
-  if (N->getOpcode() != ISD::TargetGlobalAddress)
-    return TM.getCodeModel() == CodeModel::Small;
+  if (N->getOpcode() != ISD::TargetGlobalAddress) {
+    return TM.getCodeModel() == CodeModel::Small ||
+           TM.getCodeModel() == CodeModel::Medium;
+  }
 
-  std::optional<ConstantRange> CR =
-      cast<GlobalAddressSDNode>(N)->getGlobal()->getAbsoluteSymbolRange();
-  if (!CR)
-    return TM.getCodeModel() == CodeModel::Small;
+  const GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
+  if (std::optional<ConstantRange> CR = GV->getAbsoluteSymbolRange())
+    return CR->getUnsignedMax().ult(1ull << 32);
 
-  return CR->getUnsignedMax().ult(1ull << 32);
+  if (auto *GO = GV->getAliaseeObject())
+    return !TM.isLargeGlobalObject(GO);
+  return true;
 }
 
 bool X86DAGToDAGISel::selectLEA64_32Addr(SDValue N, SDValue &Base,
diff --git a/llvm/test/CodeGen/X86/code-model-elf.ll b/llvm/test/CodeGen/X86/code-model-elf.ll
index 0f58ccaf298dab..a43736e2a5884a 100644
--- a/llvm/test/CodeGen/X86/code-model-elf.ll
+++ b/llvm/test/CodeGen/X86/code-model-elf.ll
@@ -40,6 +40,7 @@ target triple = "x86_64--linux"
 
 @global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16
 @static_data = internal global [10 x i32] zeroinitializer, align 16
+@static_data_alias = internal constant ptr getelementptr inbounds ([10 x i32], ptr @static_data, i64 0, i64 2), align 8
 @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
@@ -96,12 +97,67 @@ define dso_local ptr @lea_static_data() #0 {
 ; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L0$pb(%rip), %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $static_data@GOTOFF, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $static_data@GOTOFF, %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rcx, %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    retq
   ret ptr @static_data
 }
 
+define dso_local ptr @lea_static_data_alias() #0 {
+; SMALL-STATIC-LABEL: lea_static_data_alias:
+; SMALL-STATIC:       # %bb.0:
+; SMALL-STATIC-NEXT:    movl $static_data_alias, %eax
+; SMALL-STATIC-NEXT:    retq
+;
+; MEDIUM-STATIC-LABEL: lea_static_data_alias:
+; MEDIUM-STATIC:       # %bb.0:
+; MEDIUM-STATIC-NEXT:    movabsq $static_data_alias, %rax
+; MEDIUM-STATIC-NEXT:    retq
+;
+; LARGE-STATIC-LABEL: lea_static_data_alias:
+; LARGE-STATIC:       # %bb.0:
+; LARGE-STATIC-NEXT:    movabsq $static_data_alias, %rax
+; LARGE-STATIC-NEXT:    retq
+;
+; SMALL-PIC-LABEL: lea_static_data_alias:
+; SMALL-PIC:       # %bb.0:
+; SMALL-PIC-NEXT:    leaq static_data_alias(%rip), %rax
+; SMALL-PIC-NEXT:    retq
+;
+; MEDIUM-SMALL-DATA-PIC-LABEL: lea_static_data_alias:
+; MEDIUM-SMALL-DATA-PIC:       # %bb.0:
+; MEDIUM-SMALL-DATA-PIC-NEXT:    leaq static_data_alias(%rip), %rax
+; MEDIUM-SMALL-DATA-PIC-NEXT:    retq
+;
+; MEDIUM-PIC-LABEL: lea_static_data_alias:
+; MEDIUM-PIC:       # %bb.0:
+; MEDIUM-PIC-NEXT:    leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
+; MEDIUM-PIC-NEXT:    movabsq $static_data_alias@GOTOFF, %rax
+; MEDIUM-PIC-NEXT:    addq %rcx, %rax
+; MEDIUM-PIC-NEXT:    retq
+;
+; LARGE-PIC-LABEL: lea_static_data_alias:
+; LARGE-PIC:       # %bb.0:
+; LARGE-PIC-NEXT:  .L1$pb:
+; LARGE-PIC-NEXT:    leaq .L1$pb(%rip), %rax
+; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
+; LARGE-PIC-NEXT:    addq %rax, %rcx
+; LARGE-PIC-NEXT:    movabsq $static_data_alias@GOTOFF, %rax
+; LARGE-PIC-NEXT:    addq %rcx, %rax
+; LARGE-PIC-NEXT:    retq
+;
+; LARGE-SMALL-DATA-PIC-LABEL: lea_static_data_alias:
+; LARGE-SMALL-DATA-PIC:       # %bb.0:
+; LARGE-SMALL-DATA-PIC-NEXT:  .L1$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L1$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $static_data_alias@GOTOFF, %eax
+; LARGE-SMALL-DATA-PIC-NEXT:    addq %rcx, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    retq
+  ret ptr @static_data_alias
+}
+
 define dso_local ptr @lea_global_data() #0 {
 ; SMALL-STATIC-LABEL: lea_global_data:
 ; SMALL-STATIC:       # %bb.0:
@@ -137,9 +193,9 @@ define dso_local ptr @lea_global_data() #0 {
 ;
 ; LARGE-PIC-LABEL: lea_global_data:
 ; LARGE-PIC:       # %bb.0:
-; LARGE-PIC-NEXT:  .L1$pb:
-; LARGE-PIC-NEXT:    leaq .L1$pb(%rip), %rax
-; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
+; LARGE-PIC-NEXT:  .L2$pb:
+; LARGE-PIC-NEXT:    leaq .L2$pb(%rip), %rax
+; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx
 ; LARGE-PIC-NEXT:    addq %rax, %rcx
 ; LARGE-PIC-NEXT:    movabsq $global_data@GOTOFF, %rax
 ; LARGE-PIC-NEXT:    addq %rcx, %rax
@@ -147,11 +203,11 @@ define dso_local ptr @lea_global_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: lea_global_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L1$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L1$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L2$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L2$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $global_data@GOTOFF, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $global_data@GOTOFF, %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rcx, %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    retq
   ret ptr @global_data
@@ -190,9 +246,9 @@ define dso_local ptr @lea_extern_data() #0 {
 ;
 ; LARGE-PIC-LABEL: lea_extern_data:
 ; LARGE-PIC:       # %bb.0:
-; LARGE-PIC-NEXT:  .L2$pb:
-; LARGE-PIC-NEXT:    leaq .L2$pb(%rip), %rax
-; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx
+; LARGE-PIC-NEXT:  .L3$pb:
+; LARGE-PIC-NEXT:    leaq .L3$pb(%rip), %rax
+; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx
 ; LARGE-PIC-NEXT:    addq %rax, %rcx
 ; LARGE-PIC-NEXT:    movabsq $extern_data@GOT, %rax
 ; LARGE-PIC-NEXT:    movq (%rcx,%rax), %rax
@@ -200,11 +256,11 @@ define dso_local ptr @lea_extern_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: lea_extern_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L2$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L2$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L3$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L3$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $extern_data@GOT, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $extern_data@GOT, %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movq (%rcx,%rax), %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    retq
   ret ptr @extern_data
@@ -247,9 +303,9 @@ define dso_local ptr @lea_unknown_size_data() #0 {
 ;
 ; LARGE-PIC-LABEL: lea_unknown_size_data:
 ; LARGE-PIC:       # %bb.0:
-; LARGE-PIC-NEXT:  .L3$pb:
-; LARGE-PIC-NEXT:    leaq .L3$pb(%rip), %rax
-; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx
+; 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 $unknown_size_data@GOTOFF, %rax
 ; LARGE-PIC-NEXT:    addq %rcx, %rax
@@ -257,9 +313,9 @@ define dso_local ptr @lea_unknown_size_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: lea_unknown_size_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L3$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L3$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L4$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L4$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $unknown_size_data@GOTOFF, %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rcx, %rax
@@ -267,7 +323,6 @@ 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:
@@ -276,12 +331,12 @@ define dso_local ptr @lea_forced_small_data() #0 {
 ;
 ; MEDIUM-STATIC-LABEL: lea_forced_small_data:
 ; MEDIUM-STATIC:       # %bb.0:
-; MEDIUM-STATIC-NEXT:    movabsq $forced_small_data, %rax
+; MEDIUM-STATIC-NEXT:    movl $forced_small_data, %eax
 ; 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:    movl $forced_small_data, %eax
 ; LARGE-STATIC-NEXT:    retq
 ;
 ; SMALL-PIC-LABEL: lea_forced_small_data:
@@ -301,21 +356,21 @@ define dso_local ptr @lea_forced_small_data() #0 {
 ;
 ; 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:  .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 $forced_small_data@GOTOFF, %eax
 ; LARGE-PIC-NEXT:    addq %rcx, %rax
 ; LARGE-PIC-NEXT:    retq
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: lea_forced_small_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L4$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L4$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L5$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L5$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $forced_small_data@GOTOFF, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $forced_small_data@GOTOFF, %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rcx, %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    retq
   ret ptr @forced_small_data
@@ -330,13 +385,13 @@ define dso_local i32 @load_forced_small_data() #0 {
 ;
 ; MEDIUM-STATIC-LABEL: load_forced_small_data:
 ; MEDIUM-STATIC:       # %bb.0:
-; MEDIUM-STATIC-NEXT:    movabsq $forced_small_data, %rax
+; MEDIUM-STATIC-NEXT:    movl $forced_small_data, %eax
 ; 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 $forced_small_data, %eax
 ; LARGE-STATIC-NEXT:    movl 8(%rax), %eax
 ; LARGE-STATIC-NEXT:    retq
 ;
@@ -359,21 +414,21 @@ define dso_local i32 @load_forced_small_data() #0 {
 ;
 ; 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:  .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_small_data@GOTOFF, %rax
+; LARGE-PIC-NEXT:    movl $forced_small_data@GOTOFF, %eax
 ; LARGE-PIC-NEXT:    movl 8(%rcx,%rax), %eax
 ; LARGE-PIC-NEXT:    retq
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: load_forced_small_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L5$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L5$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L6$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L6$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $forced_small_data@GOTOFF, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $forced_small_data@GOTOFF, %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movl 8(%rcx,%rax), %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    retq
   %rv = load i32, ptr getelementptr inbounds (i32, ptr @forced_small_data, i64 2)
@@ -384,7 +439,7 @@ define dso_local i32 @load_forced_small_data() #0 {
 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:    movabsq $forced_large_data, %rax
 ; SMALL-STATIC-NEXT:    retq
 ;
 ; MEDIUM-STATIC-LABEL: lea_forced_large_data:
@@ -419,9 +474,9 @@ define dso_local ptr @lea_forced_large_data() #0 {
 ;
 ; 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:  .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:    addq %rcx, %rax
@@ -429,9 +484,9 @@ define dso_local ptr @lea_forced_large_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: lea_forced_large_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L6$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L6$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L7$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L7$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $forced_large_data@GOTOFF, %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rcx, %rax
@@ -479,9 +534,9 @@ define dso_local i32 @load_forced_large_data() #0 {
 ;
 ; 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:  .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 $forced_large_data@GOTOFF, %rax
 ; LARGE-PIC-NEXT:    movl 8(%rcx,%rax), %eax
@@ -489,9 +544,9 @@ define dso_local i32 @load_forced_large_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: load_forced_large_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L7$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L7$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L8$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L8$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L8$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $forced_large_data@GOTOFF, %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movl 8(%rcx,%rax), %eax
@@ -538,9 +593,9 @@ define dso_local i32 @load_global_data() #0 {
 ;
 ; LARGE-PIC-LABEL: load_global_data:
 ; LARGE-PIC:       # %bb.0:
-; 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:  .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 $global_data@GOTOFF, %rax
 ; LARGE-PIC-NEXT:    movl 8(%rcx,%rax), %eax
@@ -548,11 +603,11 @@ define dso_local i32 @load_global_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: load_global_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L8$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L8$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L8$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L9$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L9$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $global_data@GOTOFF, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $global_data@GOTOFF, %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movl 8(%rcx,%rax), %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    retq
   %rv = load i32, ptr getelementptr inbounds ([10 x i32], ptr @global_data, i64 0, i64 2)
@@ -598,9 +653,9 @@ define dso_local i32 @load_extern_data() #0 {
 ;
 ; LARGE-PIC-LABEL: load_extern_data:
 ; 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:  .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 $extern_data@GOT, %rax
 ; LARGE-PIC-NEXT:    movq (%rcx,%rax), %rax
@@ -609,11 +664,11 @@ define dso_local i32 @load_extern_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: load_extern_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L9$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L9$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L10$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L10$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $extern_data@GOT, %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movl $extern_data@GOT, %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movq (%rcx,%rax), %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movl 8(%rax), %eax
 ; LARGE-SMALL-DATA-PIC-NEXT:    retq
@@ -660,9 +715,9 @@ define dso_local i32 @load_unknown_size_data() #0 {
 ;
 ; LARGE-PIC-LABEL: load_unknown_size_data:
 ; 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:  .L11$pb:
+; LARGE-PIC-NEXT:    leaq .L11$pb(%rip), %rax
+; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L11$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
@@ -670,9 +725,9 @@ define dso_local i32 @load_unknown_size_data() #0 {
 ;
 ; LARGE-SMALL-DATA-PIC-LABEL: load_unknown_size_data:
 ; LARGE-SMALL-DATA-PIC:       # %bb.0:
-; LARGE-SMALL-DATA-PIC-NEXT:  .L10$pb:
-; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L10$pb(%rip), %rax
-; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx
+; LARGE-SMALL-DATA-PIC-NEXT:  .L11$pb:
+; LARGE-SMALL-DATA-PIC-NEXT:    leaq .L11$pb(%rip), %rax
+; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L11$pb, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    addq %rax, %rcx
 ; LARGE-SMALL-DATA-PIC-NEXT:    movabsq $unknown_size_data@GOTOFF, %rax
 ; LARGE-SMALL-DATA-PIC-NEXT:    movl 8(%rcx,%rax), %eax
@@ -718,9 +773,9 @@ define dso_local ptr @lea_opaque() #0 {
 ;
 ; LARGE-PIC-LABEL: lea_opaque:
 ; 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:  .L12$pb:
+; LARGE-PIC-NEXT:    leaq .L12$pb(%rip), %rax
+; LARGE-PIC-NEXT:    movabsq $_GLOBAL_OFFSET_TABLE_-.L12$pb, %rcx
 ; LARGE-PIC-NEXT:    addq %rax, %rcx
 ; LARGE-PIC-NEXT:    mo...
[truncated]

… can fit in 32 bits

For non-GlobalValue references, the small and medium code models can use 32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.
@@ -91,9 +91,8 @@ X86Subtarget::classifyLocalReference(const GlobalValue *GV) const {
if (CM == CodeModel::Large)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this condition correct? It seems like it won't handle globals explicitly marked with code_model "small" correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even a small global in the large code model cannot be referenced rip-relatively since ltext is far from all data. So it needs to use GOTOFF, whether that's a 32-bit (for small data) or 64-bit (for large data) GOTOFF.

return TM.isLargeGlobalObject(GO) ? X86II::MO_GOTOFF
: X86II::MO_NO_FLAG;
if (GV)
return TM.isLargeGlobalValue(GV) ? X86II::MO_GOTOFF : X86II::MO_NO_FLAG;
// For non-GlobalObjects, the small and medium code models treat them as
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems stale. What does it mean if GV is null? Does that represent a reference to a local label, something like a constant pool?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated comment

; LARGE-PIC: # %bb.0:
; LARGE-PIC-NEXT: .L1$pb:
; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax
; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The large PIC code model is awful. Is there really no way to express $static_data_alias - .L1$pb with a static relocation? That would avoid the need for the second add and i64 materialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is relocations only allow one symbol to relocate against, we can't just diff two symbols. so we have to take advantage of the other implicit operands in the relocations, e.g. the PC/GOT/PLT, for PIC. for example, using the GOT as an anchor requires a 64-bit relocation to get the address of the GOT. the only anchor that x86-64 static relocations provide that can be assumed to be close to the instruction is the PC, so we'd probably need to use R_X86_64_PC64 (seems like this is a rare relocation type). perhaps something like the following

  leaq .L(%rip), %rax
.L
  movabsq foo-%rip, %rbx
  addq %rbx, %rax

but now you need a label for every reference to a global. I'm not sure how much this impacts optimizations. (do optimizations take care to not move around labels if their relative placement with instructions matter?)

maybe this is worth experimenting with at some point

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I suppose the GOT materialization only happens once per function anyway, so each symbol reference really only requires one movabsq & add. So, it's not really worth further exploration.

@@ -1072,7 +1127,7 @@ define dso_local float @load_constant_pool(float %x) #0 {
;
; MEDIUM-STATIC-LABEL: load_constant_pool:
; MEDIUM-STATIC: # %bb.0:
; MEDIUM-STATIC-NEXT: movabsq ${{\.?LCPI[0-9]+_[0-9]+}}, %rax
; MEDIUM-STATIC-NEXT: movl ${{\.?LCPI[0-9]+_[0-9]+}}, %eax
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These constant pool changes look correct.

Copy link

github-actions bot commented Dec 14, 2023

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.

Copy link
Collaborator

@rnk rnk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good!

@aeubanks aeubanks merged commit 5e38ba2 into llvm:main Dec 14, 2023
4 checks passed
@aeubanks aeubanks deleted the imm32 branch December 14, 2023 17:28
aeubanks added a commit that referenced this pull request Dec 14, 2023
…eference can fit in 32 bits (#75386)"

This reverts commit 5e38ba2.
aeubanks added a commit that referenced this pull request Dec 14, 2023
…eference can fit in 32 bits" (#75500)

Reverts #75386

Breaks build.
aeubanks added a commit that referenced this pull request Dec 14, 2023
…ference can fit in 32 bits (#75386)

For non-GlobalValue references, the small and medium code models can use
32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.
Even the large code model can reference small objects with 32 bit
constants as long as we're in no-pic mode, or if the reference is offset
from the GOT.

Original commit broke the build...
@vitalybuka
Copy link
Collaborator

@ormris
Copy link
Collaborator

ormris commented Dec 14, 2023

+1 We're also seeing this failure in our internal CI.

aeubanks added a commit that referenced this pull request Dec 14, 2023
…lobal reference can fit in 32 bits (#75386)"

This reverts commit ec92d74.

Breaks some compiler-rt tests, e.g. https://lab.llvm.org/buildbot/#/builders/37/builds/28834
@aeubanks
Copy link
Contributor Author

reverted, taking a look

aeubanks added a commit that referenced this pull request Dec 14, 2023
… reference can fit in 32 bits (#75386)

For non-GlobalValue references, the small and medium code models can use
32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.
Even the large code model can reference small objects with 32 bit
constants as long as we're in no-pic mode, or if the reference is offset
from the GOT.

Original commit broke the build...

First reland broke large PIC builds referencing small data since it was using GOTOFF as a 32-bit constant.
qihangkong pushed a commit to rvgpu/rvgpu-llvm that referenced this pull request Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants