[llvm] r231474 - [AsmPrinter][TLOF] ARM64 MachO support for replacing GOT equivalents

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Fri Mar 6 05:48:46 PST 2015


Author: bruno
Date: Fri Mar  6 07:48:45 2015
New Revision: 231474

URL: http://llvm.org/viewvc/llvm-project?rev=231474&view=rev
Log:
[AsmPrinter][TLOF] ARM64 MachO support for replacing GOT equivalents

Follow up r230264 and add ARM64 support for replacing global GOT
equivalent symbol accesses by references to the GOT entry for the final
symbol instead, example:

-- before

   .globl  _foo
  _foo:
   .long   42

   .globl  _gotequivalent
  _gotequivalent:
   .quad   _foo

   .globl  _delta
  _delta:
   .long   _gotequivalent-_delta

-- after

   .globl  _foo
  _foo:
   .long   42

   .globl  _delta
  Ltmp3:
   .long _foo at GOT-Ltmp3

Added:
    llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-64.ll
      - copied, changed from r231465, llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll
Removed:
    llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll
Modified:
    llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp
    llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h
    llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp
    llvm/trunk/lib/Target/X86/X86TargetObjectFile.h

Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h?rev=231474&r1=231473&r2=231474&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h Fri Mar  6 07:48:45 2015
@@ -43,12 +43,14 @@ class TargetLoweringObjectFile : public
 
 protected:
   bool SupportIndirectSymViaGOTPCRel;
+  bool SupportGOTPCRelWithOffset;
 
 public:
   MCContext &getContext() const { return *Ctx; }
 
   TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(nullptr), DL(nullptr),
-                               SupportIndirectSymViaGOTPCRel(false) {}
+                               SupportIndirectSymViaGOTPCRel(false),
+                               SupportGOTPCRelWithOffset(true) {}
 
   virtual ~TargetLoweringObjectFile();
 
@@ -168,9 +170,16 @@ public:
     return SupportIndirectSymViaGOTPCRel;
   }
 
+  /// \brief Target GOT "PC"-relative relocation supports encoding an additional
+  /// binary expression with an offset?
+  bool supportGOTPCRelWithOffset() const {
+    return SupportGOTPCRelWithOffset;
+  }
+
   /// \brief Get the target specific PC relative GOT entry relocation
   virtual const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
-                                                  int64_t Offset) const {
+                                                  int64_t Offset,
+                                                  MCStreamer &Streamer) const {
     return nullptr;
   }
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=231474&r1=231473&r2=231474&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Fri Mar  6 07:48:45 2015
@@ -2084,9 +2084,13 @@ static void handleIndirectSymViaGOTPCRel
   //
   //    gotpcrelcst := <offset from @foo base> + <cst>
   //
+  // Only encode <cst> if the target supports it.
+  //
   int64_t GOTPCRelCst = Offset + MV.getConstant();
   if (GOTPCRelCst < 0)
     return;
+  if (!AP.getObjFileLowering().supportGOTPCRelWithOffset() && GOTPCRelCst != 0)
+    return;
 
   // Emit the GOT PC relative to replace the got equivalent global, i.e.:
   //
@@ -2110,7 +2114,8 @@ static void handleIndirectSymViaGOTPCRel
   const GlobalValue *FinalGV = dyn_cast<GlobalValue>(GV->getOperand(0));
   const MCSymbol *FinalSym = AP.getSymbol(FinalGV);
   *ME = AP.getObjFileLowering().getIndirectSymViaGOTPCRel(FinalSym,
-                                                          GOTPCRelCst);
+                                                          GOTPCRelCst,
+                                                          AP.OutStreamer);
 
   // Update GOT equivalent usage information
   --NumUses;

Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp?rev=231474&r1=231473&r2=231474&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp Fri Mar  6 07:48:45 2015
@@ -23,6 +23,12 @@ void AArch64_ELFTargetObjectFile::Initia
   InitializeELF(TM.Options.UseInitArray);
 }
 
+AArch64_MachoTargetObjectFile::AArch64_MachoTargetObjectFile()
+  : TargetLoweringObjectFileMachO() {
+  SupportIndirectSymViaGOTPCRel = true;
+  SupportGOTPCRelWithOffset = false;
+}
+
 const MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference(
     const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
     const TargetMachine &TM, MachineModuleInfo *MMI,
@@ -50,3 +56,15 @@ MCSymbol *AArch64_MachoTargetObjectFile:
     MachineModuleInfo *MMI) const {
   return TM.getSymbol(GV, Mang);
 }
+
+const MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
+    const MCSymbol *Sym, int64_t Offset, MCStreamer &Streamer) const {
+  // On ARM64 Darwin, we can reference symbols with foo at GOT-., which
+  // is an indirect pc-relative reference.
+  const MCExpr *Res =
+      MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOT, getContext());
+  MCSymbol *PCSym = getContext().CreateTempSymbol();
+  Streamer.EmitLabel(PCSym);
+  const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, getContext());
+  return MCBinaryExpr::CreateSub(Res, PC, getContext());
+}

Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h?rev=231474&r1=231473&r2=231474&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h Fri Mar  6 07:48:45 2015
@@ -24,6 +24,8 @@ class AArch64_ELFTargetObjectFile : publ
 /// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.
 class AArch64_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
 public:
+  AArch64_MachoTargetObjectFile();
+
   const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
                                         unsigned Encoding, Mangler &Mang,
                                         const TargetMachine &TM,
@@ -33,6 +35,10 @@ public:
   MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
                                     const TargetMachine &TM,
                                     MachineModuleInfo *MMI) const override;
+
+  const MCExpr *
+    getIndirectSymViaGOTPCRel(const MCSymbol *Sym, int64_t Offset,
+                              MCStreamer &Streamer) const override;
 };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp?rev=231474&r1=231473&r2=231474&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86TargetObjectFile.cpp Fri Mar  6 07:48:45 2015
@@ -52,7 +52,7 @@ MCSymbol *X86_64MachoTargetObjectFile::g
 }
 
 const MCExpr *X86_64MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
-    const MCSymbol *Sym, int64_t Offset) const {
+    const MCSymbol *Sym, int64_t Offset, MCStreamer &Streamer) const {
   // On Darwin/X86-64, we need to use foo at GOTPCREL+4 to access the got entry
   // from a data section. In case there's an additional offset, then use
   // foo at GOTPCREL+4+<offset>.

Modified: llvm/trunk/lib/Target/X86/X86TargetObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetObjectFile.h?rev=231474&r1=231473&r2=231474&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86TargetObjectFile.h (original)
+++ llvm/trunk/lib/Target/X86/X86TargetObjectFile.h Fri Mar  6 07:48:45 2015
@@ -34,8 +34,8 @@ namespace llvm {
                                       MachineModuleInfo *MMI) const override;
 
     const MCExpr *
-      getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
-                                int64_t Offset) const override;
+      getIndirectSymViaGOTPCRel(const MCSymbol *Sym, int64_t Offset,
+                                MCStreamer &Streamer) const override;
   };
 
   /// \brief This implemenatation is used for X86 ELF targets that don't

Copied: llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-64.ll (from r231465, llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-64.ll?p2=llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-64.ll&p1=llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll&r1=231465&r2=231474&rev=231474&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll (original)
+++ llvm/trunk/test/MC/MachO/cstexpr-gotpcrel-64.ll Fri Mar  6 07:48:45 2015
@@ -1,6 +1,9 @@
 ; RUN: llc -mtriple=x86_64-apple-darwin %s -o %t
-; RUN: FileCheck %s < %t
-; RUN: FileCheck %s -check-prefix=GOT-EQUIV < %t
+; RUN:  FileCheck %s -check-prefix=X86 < %t
+; RUN:  FileCheck %s -check-prefix=X86-GOT-EQUIV < %t
+; RUN: llc -mtriple=arm64-apple-darwin %s -o %t
+; RUN:  FileCheck %s -check-prefix=ARM < %t
+; RUN:  FileCheck %s -check-prefix=ARM-GOT-EQUIV < %t
 
 ; GOT equivalent globals references can be replaced by the GOT entry of the
 ; final symbol instead.
@@ -8,9 +11,15 @@
 %struct.data = type { i32, %struct.anon }
 %struct.anon = type { i32, i32 }
 
-; Check that these got equivalent symbols are never emitted or used
-; GOT-EQUIV-NOT: _localgotequiv
-; GOT-EQUIV-NOT: _extgotequiv
+; Check that these got equivalent symbols are never emitted on x86-64 and
+; emitted on ARM64. Since ARM64 does not support encoding an extra offset with
+; @GOT, we still need to emit the equivalents for use by such IR constructs.
+
+; X86-GOT-EQUIV-NOT: L_localgotequiv
+; X86-GOT-EQUIV-NOT: l_extgotequiv
+
+; ARM-GOT-EQUIV-LABEL: l_extgotequiv:
+; ARM-GOT-EQUIV-LABEL: l_localgotequiv:
 @localfoo = global i32 42
 @localgotequiv = private unnamed_addr constant i32* @localfoo
 
@@ -21,35 +30,54 @@
 ; equivalent since it can't be replaced by the GOT entry. @bargotequiv is
 ; used by an instruction inside @t0.
 ;
-; CHECK: l_bargotequiv:
-; CHECK-NEXT:  .quad   _extbar
+; X86: l_bargotequiv:
+; X86-NEXT:  .quad   _extbar
+; ARM: l_bargotequiv:
+; ARM-NEXT:  .quad   _extbar
 @extbar = external global i32
 @bargotequiv = private unnamed_addr constant i32* @extbar
 
 @table = global [4 x %struct.data] [
-; CHECK-LABEL: _table
+; X86-LABEL: _table
+; ARM-LABEL: _table
   %struct.data { i32 1, %struct.anon { i32 2, i32 3 } },
 ; Test GOT equivalent usage inside nested constant arrays.
-; CHECK: .long   5
-; CHECK-NOT: .long   _localgotequiv-(_table+20)
-; CHECK-NEXT: .long   _localfoo at GOTPCREL+4
+
+; X86: .long   5
+; X86-NOT: .long   _localgotequiv-(_table+20)
+; X86-NEXT: .long   _localfoo at GOTPCREL+4
+
+; ARM: .long   5
+; ARM-NOT: .long   _localgotequiv-(_table+20)
+; ARM-NEXT: Ltmp1:
+; ARM-NEXT: .long _localfoo at GOT-Ltmp1
   %struct.data { i32 4, %struct.anon { i32 5,
     i32 trunc (i64 sub (i64 ptrtoint (i32** @localgotequiv to i64),
                         i64 ptrtoint (i32* getelementptr inbounds ([4 x %struct.data]* @table, i32 0, i64 1, i32 1, i32 1) to i64))
                         to i32)}
   },
-; CHECK: .long   5
-; CHECK-NOT: _extgotequiv-(_table+32)
-; CHECK-NEXT: .long   _extfoo at GOTPCREL+4
+; X86: .long   5
+; X86-NOT: _extgotequiv-(_table+32)
+; X86-NEXT: .long   _extfoo at GOTPCREL+4
+
+; ARM: .long   5
+; ARM-NOT: _extgotequiv-(_table+32)
+; ARM-NEXT: Ltmp2:
+; ARM-NEXT: _extfoo at GOT-Ltmp2
   %struct.data { i32 4, %struct.anon { i32 5,
     i32 trunc (i64 sub (i64 ptrtoint (i32** @extgotequiv to i64),
                         i64 ptrtoint (i32* getelementptr inbounds ([4 x %struct.data]* @table, i32 0, i64 2, i32 1, i32 1) to i64))
                         to i32)}
   },
-; Test support for arbitrary constants into the GOTPCREL offset
-; CHECK: .long   5
-; CHECK-NOT: _extgotequiv-(_table+44)
-; CHECK-NEXT: .long   _extfoo at GOTPCREL+28
+; Test support for arbitrary constants into the GOTPCREL offset, which is
+; supported on x86-64 but not on ARM64
+
+; X86: .long   5
+; X86-NOT: _extgotequiv-(_table+44)
+; X86-NEXT: .long   _extfoo at GOTPCREL+28
+
+; ARM: .long   5
+; ARM-NEXT: .long (l_extgotequiv-(_table+44))+24
   %struct.data { i32 4, %struct.anon { i32 5,
     i32 add (i32 trunc (i64 sub (i64 ptrtoint (i32** @extgotequiv to i64),
                                  i64 ptrtoint (i32* getelementptr inbounds ([4 x %struct.data]* @table, i32 0, i64 3, i32 1, i32 1) to i64))
@@ -58,14 +86,22 @@
 ], align 16
 
 ; Test multiple uses of GOT equivalents.
-; CHECK-LABEL: _delta
-; CHECK: .long   _extfoo at GOTPCREL+4
+
+; X86-LABEL: _delta
+; X86: .long   _extfoo at GOTPCREL+4
+
+; ARM-LABEL: _delta
+; ARM: Ltmp3:
+; ARM-NEXT:  .long _extfoo at GOT-Ltmp3
 @delta = global i32 trunc (i64 sub (i64 ptrtoint (i32** @extgotequiv to i64),
                                     i64 ptrtoint (i32* @delta to i64))
                            to i32)
 
-; CHECK-LABEL: _deltaplus:
-; CHECK: .long   _localfoo at GOTPCREL+59
+; X86-LABEL: _deltaplus:
+; X86: .long   _localfoo at GOTPCREL+59
+
+; ARM-LABEL: _deltaplus:
+; ARM: .long  (l_localgotequiv-_deltaplus)+55
 @deltaplus = global i32 add (i32 trunc (i64 sub (i64 ptrtoint (i32** @localgotequiv to i64),
                                         i64 ptrtoint (i32* @deltaplus to i64))
                                         to i32), i32 55)

Removed: llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll?rev=231473&view=auto
==============================================================================
--- llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll (original)
+++ llvm/trunk/test/MC/X86/cstexpr-gotpcrel.ll (removed)
@@ -1,78 +0,0 @@
-; RUN: llc -mtriple=x86_64-apple-darwin %s -o %t
-; RUN: FileCheck %s < %t
-; RUN: FileCheck %s -check-prefix=GOT-EQUIV < %t
-
-; GOT equivalent globals references can be replaced by the GOT entry of the
-; final symbol instead.
-
-%struct.data = type { i32, %struct.anon }
-%struct.anon = type { i32, i32 }
-
-; Check that these got equivalent symbols are never emitted or used
-; GOT-EQUIV-NOT: _localgotequiv
-; GOT-EQUIV-NOT: _extgotequiv
- at localfoo = global i32 42
- at localgotequiv = private unnamed_addr constant i32* @localfoo
-
- at extfoo = external global i32
- at extgotequiv = private unnamed_addr constant i32* @extfoo
-
-; Don't replace GOT equivalent usage within instructions and emit the GOT
-; equivalent since it can't be replaced by the GOT entry. @bargotequiv is
-; used by an instruction inside @t0.
-;
-; CHECK: l_bargotequiv:
-; CHECK-NEXT:  .quad   _extbar
- at extbar = external global i32
- at bargotequiv = private unnamed_addr constant i32* @extbar
-
- at table = global [4 x %struct.data] [
-; CHECK-LABEL: _table
-  %struct.data { i32 1, %struct.anon { i32 2, i32 3 } },
-; Test GOT equivalent usage inside nested constant arrays.
-; CHECK: .long   5
-; CHECK-NOT: .long   _localgotequiv-(_table+20)
-; CHECK-NEXT: .long   _localfoo at GOTPCREL+4
-  %struct.data { i32 4, %struct.anon { i32 5,
-    i32 trunc (i64 sub (i64 ptrtoint (i32** @localgotequiv to i64),
-                        i64 ptrtoint (i32* getelementptr inbounds ([4 x %struct.data]* @table, i32 0, i64 1, i32 1, i32 1) to i64))
-                        to i32)}
-  },
-; CHECK: .long   5
-; CHECK-NOT: _extgotequiv-(_table+32)
-; CHECK-NEXT: .long   _extfoo at GOTPCREL+4
-  %struct.data { i32 4, %struct.anon { i32 5,
-    i32 trunc (i64 sub (i64 ptrtoint (i32** @extgotequiv to i64),
-                        i64 ptrtoint (i32* getelementptr inbounds ([4 x %struct.data]* @table, i32 0, i64 2, i32 1, i32 1) to i64))
-                        to i32)}
-  },
-; Test support for arbitrary constants into the GOTPCREL offset
-; CHECK: .long   5
-; CHECK-NOT: _extgotequiv-(_table+44)
-; CHECK-NEXT: .long   _extfoo at GOTPCREL+28
-  %struct.data { i32 4, %struct.anon { i32 5,
-    i32 add (i32 trunc (i64 sub (i64 ptrtoint (i32** @extgotequiv to i64),
-                                 i64 ptrtoint (i32* getelementptr inbounds ([4 x %struct.data]* @table, i32 0, i64 3, i32 1, i32 1) to i64))
-                                 to i32), i32 24)}
-  }
-], align 16
-
-; Test multiple uses of GOT equivalents.
-; CHECK-LABEL: _delta
-; CHECK: .long   _extfoo at GOTPCREL+4
- at delta = global i32 trunc (i64 sub (i64 ptrtoint (i32** @extgotequiv to i64),
-                                    i64 ptrtoint (i32* @delta to i64))
-                           to i32)
-
-; CHECK-LABEL: _deltaplus:
-; CHECK: .long   _localfoo at GOTPCREL+59
- at deltaplus = global i32 add (i32 trunc (i64 sub (i64 ptrtoint (i32** @localgotequiv to i64),
-                                        i64 ptrtoint (i32* @deltaplus to i64))
-                                        to i32), i32 55)
-
-define i32 @t0(i32 %a) {
-  %x = add i32 trunc (i64 sub (i64 ptrtoint (i32** @bargotequiv to i64),
-                               i64 ptrtoint (i32 (i32)* @t0 to i64))
-                           to i32), %a
-  ret i32 %x
-}





More information about the llvm-commits mailing list