Revert "Stop increasing alignment of externally-visible globals on ELF platforms."
authorJames Y Knight <jyknight@google.com>
Thu, 14 Jan 2016 16:33:21 +0000 (16:33 +0000)
committerJames Y Knight <jyknight@google.com>
Thu, 14 Jan 2016 16:33:21 +0000 (16:33 +0000)
This reverts commit r257719, due to PR26144.

llvm-svn: 257775

llvm/include/llvm/IR/GlobalValue.h
llvm/lib/CodeGen/CodeGenPrepare.cpp
llvm/lib/IR/Globals.cpp
llvm/lib/Transforms/Utils/Local.cpp
llvm/test/CodeGen/ARM/memfunc.ll

index fa6469a..4fa4e7d 100644 (file)
@@ -346,10 +346,6 @@ public:
     return !(isDeclarationForLinker() || isWeakForLinker());
   }
 
-  // Returns true if the alignment of the value can be unilaterally
-  // increased.
-  bool canIncreaseAlignment() const;
-
   /// This method unlinks 'this' from the containing module, but does not delete
   /// it.
   virtual void removeFromParent() = 0;
index fd4ee46..03e5778 100644 (file)
@@ -1742,8 +1742,8 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool& ModifiedDT) {
       // over-aligning global variables that have an explicit section is
       // forbidden.
       GlobalVariable *GV;
-      if ((GV = dyn_cast<GlobalVariable>(Val)) && GV->canIncreaseAlignment() &&
-          GV->getAlignment() < PrefAlign &&
+      if ((GV = dyn_cast<GlobalVariable>(Val)) && GV->hasUniqueInitializer() &&
+          !GV->hasSection() && GV->getAlignment() < PrefAlign &&
           DL->getTypeAllocSize(GV->getType()->getElementType()) >=
               MinSize + Offset2)
         GV->setAlignment(PrefAlign);
index a61b62b..6159f93 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/IR/GlobalValue.h"
 #include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/Triple.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/GlobalAlias.h"
-#include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
@@ -135,47 +134,6 @@ bool GlobalValue::isDeclaration() const {
   return false;
 }
 
-bool GlobalValue::canIncreaseAlignment() const {
-  // Firstly, can only increase the alignment of a global if it
-  // is a strong definition.
-  if (!isStrongDefinitionForLinker())
-    return false;
-
-  // It also has to either not have a section defined, or, not have
-  // alignment specified. (If it is assigned a section, the global
-  // could be densely packed with other objects in the section, and
-  // increasing the alignment could cause padding issues.)
-  if (hasSection() && getAlignment() > 0)
-    return false;
-
-  // On ELF platforms, we're further restricted in that we can't
-  // increase the alignment of any variable which might be emitted
-  // into a shared library, and which is exported. If the main
-  // executable accesses a variable found in a shared-lib, the main
-  // exe actually allocates memory for and exports the symbol ITSELF,
-  // overriding the symbol found in the library. That is, at link
-  // time, the observed alignment of the variable is copied into the
-  // executable binary. (A COPY relocation is also generated, to copy
-  // the initial data from the shadowed variable in the shared-lib
-  // into the location in the main binary, before running code.)
-  //
-  // And thus, even though you might think you are defining the
-  // global, and allocating the memory for the global in your object
-  // file, and thus should be able to set the alignment arbitrarily,
-  // that's not actually true. Doing so can cause an ABI breakage; an
-  // executable might have already been built with the previous
-  // alignment of the variable, and then assuming an increased
-  // alignment will be incorrect.
-
-  // Conservatively assume ELF if there's no parent pointer.
-  bool isELF =
-      (!Parent || Triple(Parent->getTargetTriple()).isOSBinFormatELF());
-  if (isELF && hasDefaultVisibility() && !hasLocalLinkage())
-    return false;
-
-  return true;
-}
-
 //===----------------------------------------------------------------------===//
 // GlobalVariable Implementation
 //===----------------------------------------------------------------------===//
index 91b3499..d2793e5 100644 (file)
@@ -944,31 +944,37 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
 static unsigned enforceKnownAlignment(Value *V, unsigned Align,
                                       unsigned PrefAlign,
                                       const DataLayout &DL) {
-  assert(PrefAlign > Align);
-
   V = V->stripPointerCasts();
 
   if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
-    assert(AI->getAlignment() <= Align);
     // If the preferred alignment is greater than the natural stack alignment
     // then don't round up. This avoids dynamic stack realignment.
     if (DL.exceedsNaturalStackAlignment(PrefAlign))
       return Align;
+    // If there is a requested alignment and if this is an alloca, round up.
+    if (AI->getAlignment() >= PrefAlign)
+      return AI->getAlignment();
     AI->setAlignment(PrefAlign);
     return PrefAlign;
   }
 
   if (auto *GO = dyn_cast<GlobalObject>(V)) {
-    assert(GO->getAlignment() <= Align);
     // If there is a large requested alignment and we can, bump up the alignment
     // of the global.  If the memory we set aside for the global may not be the
     // memory used by the final program then it is impossible for us to reliably
     // enforce the preferred alignment.
-    if (!GO->canIncreaseAlignment())
+    if (!GO->isStrongDefinitionForLinker())
       return Align;
 
-    GO->setAlignment(PrefAlign);
-    return PrefAlign;
+    if (GO->getAlignment() >= PrefAlign)
+      return GO->getAlignment();
+    // We can only increase the alignment of the global if it has no alignment
+    // specified or if it is not assigned a section.  If it is assigned a
+    // section, the global could be densely packed with other objects in the
+    // section, increasing the alignment could cause padding issues.
+    if (!GO->hasSection() || GO->getAlignment() == 0)
+      GO->setAlignment(PrefAlign);
+    return GO->getAlignment();
   }
 
   return Align;
index 46fef76..66743f3 100644 (file)
@@ -1,10 +1,10 @@
-; RUN: llc < %s -mtriple=armv7-apple-ios -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-IOS --check-prefix=CHECK
-; RUN: llc < %s -mtriple=thumbv7m-none-macho -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-DARWIN --check-prefix=CHECK
-; RUN: llc < %s -mtriple=arm-none-eabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
-; RUN: llc < %s -mtriple=arm-none-eabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
-; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
-; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
-; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
+; RUN: llc < %s -mtriple=armv7-apple-ios -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-IOS
+; RUN: llc < %s -mtriple=thumbv7m-none-macho -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-DARWIN
+; RUN: llc < %s -mtriple=arm-none-eabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
+; RUN: llc < %s -mtriple=arm-none-eabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
+; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
+; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
+; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
 
 define void @f1(i8* %dest, i8* %src) {
 entry:
@@ -402,8 +402,8 @@ entry:
 ; CHECK: arr1:
 ; CHECK-IOS: .align 3
 ; CHECK-DARWIN: .align 2
-; CHECK-EABI-NOT: .align
-; CHECK-GNUEABI-NOT: .align
+; CHECK-EABI: .align 2
+; CHECK-GNUEABI: .align 2
 ; CHECK: arr2:
 ; CHECK: {{\.section.+foo,bar}}
 ; CHECK-NOT: .align