[llvm] 2a2f02e - [X86] Use 64-bit jump table entries for large code model PIC

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 31 14:13:48 PDT 2023


Author: Arthur Eubanks
Date: 2023-08-31T14:13:38-07:00
New Revision: 2a2f02e19f7737966592f24aa4354286d9756bd9

URL: https://github.com/llvm/llvm-project/commit/2a2f02e19f7737966592f24aa4354286d9756bd9
DIFF: https://github.com/llvm/llvm-project/commit/2a2f02e19f7737966592f24aa4354286d9756bd9.diff

LOG: [X86] Use 64-bit jump table entries for large code model PIC

With the large code model, the label difference may not fit into 32 bits.
Even if we assume that any individual function is no larger than 2^32
and use a difference from the function entry to the target destination,
things like BOLT can rearrange blocks (even if BOLT doesn't necessarily
work with the large code model right now).

set directives avoid static relocations in some 32-bit entry cases, but
don't worry about set directives for 64-bit jump table entries (we can
do that later if somebody really cares about it).

check-llvm in a bootstrapped clang with the large code model passes.

Fixes #62894

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D159297

Added: 
    llvm/test/CodeGen/X86/large-pic-jump-table.ll

Modified: 
    llvm/include/llvm/CodeGen/MIRYamlMapping.h
    llvm/include/llvm/CodeGen/MachineJumpTableInfo.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/lib/CodeGen/MachineFunction.cpp
    llvm/lib/Target/X86/X86ISelLoweringCall.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index 16e773c1864181..bf35febb805762 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -137,6 +137,8 @@ template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
                 MachineJumpTableInfo::EK_GPRel32BlockAddress);
     IO.enumCase(EntryKind, "label-
diff erence32",
                 MachineJumpTableInfo::EK_LabelDifference32);
+    IO.enumCase(EntryKind, "label-
diff erence64",
+                MachineJumpTableInfo::EK_LabelDifference64);
     IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline);
     IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32);
   }

diff  --git a/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h b/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h
index 1d082bd03e5b5e..e8e9c2f6338e06 100644
--- a/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -67,6 +67,12 @@ class MachineJumpTableInfo {
     ///      .word L4_5_set_123
     EK_LabelDifference32,
 
+    /// EK_LabelDifference64 - Each entry is the address of the block minus
+    /// the address of the jump table.  This is used for PIC jump tables where
+    /// gprel64 is not supported.  e.g.:
+    ///      .quad LBB123 - LJTI1_2
+    EK_LabelDifference64,
+
     /// EK_Inline - Jump table entries are emitted inline at their point of
     /// use. It is the responsibility of the target to emit the entries.
     EK_Inline,
@@ -75,6 +81,7 @@ class MachineJumpTableInfo {
     /// TargetLowering::LowerCustomJumpTableEntry hook.
     EK_Custom32
   };
+
 private:
   JTEntryKind EntryKind;
   std::vector<MachineJumpTableEntry> JumpTables;

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 6292586c5b875e..2ce08a2ff43955 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2571,7 +2571,8 @@ void AsmPrinter::emitJumpTableInfo() {
   const Function &F = MF->getFunction();
   const TargetLoweringObjectFile &TLOF = getObjFileLowering();
   bool JTInDiffSection = !TLOF.shouldPutJumpTableInFunctionSection(
-      MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32,
+      MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
+          MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference64,
       F);
   if (JTInDiffSection) {
     // Drop it in the readonly section.
@@ -2669,7 +2670,8 @@ void AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo *MJTI,
     return;
   }
 
-  case MachineJumpTableInfo::EK_LabelDifference32: {
+  case MachineJumpTableInfo::EK_LabelDifference32:
+  case MachineJumpTableInfo::EK_LabelDifference64: {
     // Each entry is the address of the block minus the address of the jump
     // table. This is used for PIC jump tables where gprel32 is not supported.
     // e.g.:
@@ -2677,7 +2679,8 @@ void AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo *MJTI,
     // If the .set directive avoids relocations, this is emitted as:
     //      .set L4_5_set_123, LBB123 - LJTI1_2
     //      .word L4_5_set_123
-    if (MAI->doesSetDirectiveSuppressReloc()) {
+    if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&
+        MAI->doesSetDirectiveSuppressReloc()) {
       Value = MCSymbolRefExpr::create(GetJTSetSymbol(UID, MBB->getNumber()),
                                       OutContext);
       break;

diff  --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 47a18ec89ca08c..cc68991f59b312 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -3545,6 +3545,7 @@ void CodeViewDebug::collectDebugInfoForJumpTables(const MachineFunction *MF,
           break;
         case MachineJumpTableInfo::EK_Inline:
         case MachineJumpTableInfo::EK_LabelDifference32:
+        case MachineJumpTableInfo::EK_LabelDifference64:
           // Ask the AsmPrinter.
           std::tie(Base, BaseOffset, Branch, EntrySize) =
               Asm->getCodeViewJumpTableInfo(JumpTableIndex, &BranchMI, Branch);

diff  --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 88939e96e07f55..e1f9488a1c88f3 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -1244,6 +1244,7 @@ unsigned MachineJumpTableInfo::getEntrySize(const DataLayout &TD) const {
   case MachineJumpTableInfo::EK_BlockAddress:
     return TD.getPointerSize();
   case MachineJumpTableInfo::EK_GPRel64BlockAddress:
+  case MachineJumpTableInfo::EK_LabelDifference64:
     return 8;
   case MachineJumpTableInfo::EK_GPRel32BlockAddress:
   case MachineJumpTableInfo::EK_LabelDifference32:
@@ -1264,6 +1265,7 @@ unsigned MachineJumpTableInfo::getEntryAlignment(const DataLayout &TD) const {
   case MachineJumpTableInfo::EK_BlockAddress:
     return TD.getPointerABIAlignment(0).value();
   case MachineJumpTableInfo::EK_GPRel64BlockAddress:
+  case MachineJumpTableInfo::EK_LabelDifference64:
     return TD.getABIIntegerTypeAlignment(64).value();
   case MachineJumpTableInfo::EK_GPRel32BlockAddress:
   case MachineJumpTableInfo::EK_LabelDifference32:

diff  --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index a9f84d1fb61223..754d2042105e57 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -413,6 +413,9 @@ unsigned X86TargetLowering::getJumpTableEncoding() const {
   // symbol.
   if (isPositionIndependent() && Subtarget.isPICStyleGOT())
     return MachineJumpTableInfo::EK_Custom32;
+  if (isPositionIndependent() &&
+      getTargetMachine().getCodeModel() == CodeModel::Large)
+    return MachineJumpTableInfo::EK_LabelDifference64;
 
   // Otherwise, use the normal jump table encoding heuristics.
   return TargetLowering::getJumpTableEncoding();
@@ -512,7 +515,9 @@ const MCExpr *X86TargetLowering::
 getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI,
                              MCContext &Ctx) const {
   // X86-64 uses RIP relative addressing based on the jump table label.
-  if (Subtarget.isPICStyleRIPRel())
+  if (Subtarget.isPICStyleRIPRel() ||
+      (Subtarget.is64Bit() &&
+       getTargetMachine().getCodeModel() == CodeModel::Large))
     return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx);
 
   // Otherwise, the reference is relative to the PIC base.

diff  --git a/llvm/test/CodeGen/X86/large-pic-jump-table.ll b/llvm/test/CodeGen/X86/large-pic-jump-table.ll
new file mode 100644
index 00000000000000..89e8521e700a09
--- /dev/null
+++ b/llvm/test/CodeGen/X86/large-pic-jump-table.ll
@@ -0,0 +1,39 @@
+; RUN: llc -code-model=large -relocation-model=pic %s -o - | FileCheck %s
+
+target triple = "x86_64-linux-gnu"
+
+define i32 @f(i32 %i) {
+bb:
+  switch i32 %i, label %bb4 [
+    i32 0, label %bb0
+    i32 1, label %bb1
+    i32 2, label %bb2
+    i32 3, label %bb3
+  ]
+
+bb0:
+  ret i32 1
+
+bb1:
+  ret i32 100
+
+bb2:
+  ret i32 200
+
+bb3:
+  ret i32 400
+
+bb4:
+  ret i32 300
+}
+
+; CHECK:      movabsq $.LJTI0_0 at GOTOFF, [[R1:%r[a-z]{2}]]
+; CHECK-NEXT: addq    [[R1]], [[R2:%r[a-z]{2}]]
+; CHECK-NEXT: addq    ([[R2]],[[R3:%r[a-z]{2}]],8), [[R2]]
+; CHECK-NEXT: jmpq    *[[R2]]
+
+; CHECK: .LJTI0_0:
+; CHECK-NEXT: .quad   .LBB0_2-.LJTI0_0
+; CHECK-NEXT: .quad   .LBB0_3-.LJTI0_0
+; CHECK-NEXT: .quad   .LBB0_4-.LJTI0_0
+; CHECK-NEXT: .quad   .LBB0_5-.LJTI0_0


        


More information about the llvm-commits mailing list