[PATCH] X86: Work around a bfd ld quirk wrt GOTTPOFF relocation processing

David Majnemer david.majnemer at gmail.com
Mon Jan 5 02:44:43 PST 2015


Hi chandlerc, echristo, hansw, rafael,

bfd ld has a quirk which surfaces when transitioning a initial-exec
model relocation to a local-exec style code sequence.

However, it expects the R_X86_64_GOTTPOFF relocation to target a movq or
addq instruction and will fatally error if we have shrunk the load to a
movl or addl.

Work around this by prohibiting the truncation of such loads.

This fixes PR22083.

N.B. It could be argued that this isn't a bug in bfd ld because the
"ELF Handling for Thread-Local Storage" declares that GOTTPOFF be used
with addq and movq exclusively.  However, bfd ld is happy to 'Do The
Right Thing' (TM) in X32 mode and gold has no qualms acting on a
movl/addl.

http://reviews.llvm.org/D6839

Files:
  lib/Target/X86/X86ISelLowering.cpp
  lib/Target/X86/X86ISelLowering.h
  test/CodeGen/X86/tls-models.ll

Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -3862,6 +3862,32 @@
   return false;
 }
 
+bool X86TargetLowering::shouldReduceLoadWidth(SDNode *Load,
+                                              ISD::LoadExtType ExtTy,
+                                              EVT NewVT) const {
+  // The linker may attempt to transition a relocation from the initial-exec to
+  // the local-exec model as an optimization; this optimization is possible when
+  // the DSO contains both the relocation and the symbol.
+  //
+  // Notionally, this is equivalent to taking:
+  //  'movq symbol at gottpoff(%rip), %register'
+  // and transforming it into:
+  //  'movq $symbol, %register'
+  //
+  // Similarly, the following:
+  //  'addq symbol at gottpoff(%rip), %register'
+  // is also equivalent to:
+  //  'leaq symbol(%register), %register'
+  //
+  // However, bfd ld will error fatally if we shrink the load from a 'movq' to a
+  // 'movl'.  Work around this quirk by refusing to shrink such loads.
+  SDValue BasePtr = cast<LoadSDNode>(Load)->getBasePtr();
+  if (BasePtr.getOpcode() == X86ISD::WrapperRIP)
+    if (const auto *GA = dyn_cast<GlobalAddressSDNode>(BasePtr.getOperand(0)))
+      return GA->getTargetFlags() != X86II::MO_GOTTPOFF;
+  return true;
+}
+
 /// \brief Returns true if it is beneficial to convert a load of a constant
 /// to just the constant itself.
 bool X86TargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
Index: lib/Target/X86/X86ISelLowering.h
===================================================================
--- lib/Target/X86/X86ISelLowering.h
+++ lib/Target/X86/X86ISelLowering.h
@@ -770,6 +770,11 @@
       return !X86ScalarSSEf64 || VT == MVT::f80;
     }
 
+    /// Return true if we believe it is correct and profitable to reduce the
+    /// load node to a smaller type.
+    bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy,
+                               EVT NewVT) const override;
+
     const X86Subtarget* getSubtarget() const {
       return Subtarget;
     }
Index: test/CodeGen/X86/tls-models.ll
===================================================================
--- test/CodeGen/X86/tls-models.ll
+++ test/CodeGen/X86/tls-models.ll
@@ -128,6 +128,14 @@
   ; DARWIN:  _internal_ie at TLVP
 }
 
+define i32 @PR22083() {
+entry:
+  ret i32 ptrtoint (i32* @external_ie to i32)
+  ; X64-LABEL:     PR22083:
+  ; X64:     movq    external_ie at GOTTPOFF(%rip), %rax
+  ; X64_PIC-LABEL: PR22083:
+  ; X64_PIC: movq    external_ie at GOTTPOFF(%rip), %rax
+}
 
 ; ----- localexec specified -----

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D6839.17791.patch
Type: text/x-patch
Size: 2705 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150105/42a68581/attachment.bin>


More information about the llvm-commits mailing list