[llvm] r181175 - Fix const merging when an alias of a const is llvm.used.

Rafael Espindola rafael.espindola at gmail.com
Sun May 5 18:48:56 PDT 2013


Author: rafael
Date: Sun May  5 20:48:55 2013
New Revision: 181175

URL: http://llvm.org/viewvc/llvm-project?rev=181175&view=rev
Log:
Fix const merging when an alias of a const is llvm.used.

We used to disable constant merging not only if a constant is llvm.used, but
also if an alias of a constant is llvm.used. This change fixes that.

Modified:
    llvm/trunk/include/llvm/IR/Value.h
    llvm/trunk/lib/IR/Value.cpp
    llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp
    llvm/trunk/test/Transforms/ConstantMerge/merge-both.ll

Modified: llvm/trunk/include/llvm/IR/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=181175&r1=181174&r2=181175&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Value.h (original)
+++ llvm/trunk/include/llvm/IR/Value.h Sun May  5 20:48:55 2013
@@ -260,14 +260,24 @@ public:
   /// this value.
   bool hasValueHandle() const { return HasValueHandle; }
 
-  /// stripPointerCasts - This method strips off any unneeded pointer casts and
-  /// all-zero GEPs from the specified value, returning the original uncasted
-  /// value. If this is called on a non-pointer value, it returns 'this'.
+  /// \brief This method strips off any unneeded pointer casts,
+  /// all-zero GEPs and aliases from the specified value, returning the original
+  /// uncasted value. If this is called on a non-pointer value, it returns
+  /// 'this'.
   Value *stripPointerCasts();
   const Value *stripPointerCasts() const {
     return const_cast<Value*>(this)->stripPointerCasts();
   }
 
+  /// \brief This method strips off any unneeded pointer casts and
+  /// all-zero GEPs from the specified value, returning the original
+  /// uncasted value. If this is called on a non-pointer value, it returns
+  /// 'this'.
+  Value *stripPointerCastsNoFollowAliases();
+  const Value *stripPointerCastsNoFollowAliases() const {
+    return const_cast<Value*>(this)->stripPointerCastsNoFollowAliases();
+  }
+
   /// stripInBoundsConstantOffsets - This method strips off unneeded pointer casts and
   /// all-constant GEPs from the specified value, returning the original
   /// pointer value. If this is called on a non-pointer value, it returns

Modified: llvm/trunk/lib/IR/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Value.cpp?rev=181175&r1=181174&r2=181175&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Value.cpp (original)
+++ llvm/trunk/lib/IR/Value.cpp Sun May  5 20:48:55 2013
@@ -333,6 +333,7 @@ namespace {
 // Various metrics for how much to strip off of pointers.
 enum PointerStripKind {
   PSK_ZeroIndices,
+  PSK_ZeroIndicesAndAliases,
   PSK_InBoundsConstantIndices,
   PSK_InBounds
 };
@@ -350,6 +351,7 @@ static Value *stripPointerCastsAndOffset
   do {
     if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
       switch (StripKind) {
+      case PSK_ZeroIndicesAndAliases:
       case PSK_ZeroIndices:
         if (!GEP->hasAllZeroIndices())
           return V;
@@ -367,7 +369,7 @@ static Value *stripPointerCastsAndOffset
     } else if (Operator::getOpcode(V) == Instruction::BitCast) {
       V = cast<Operator>(V)->getOperand(0);
     } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
-      if (GA->mayBeOverridden())
+      if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden())
         return V;
       V = GA->getAliasee();
     } else {
@@ -381,6 +383,10 @@ static Value *stripPointerCastsAndOffset
 } // namespace
 
 Value *Value::stripPointerCasts() {
+  return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this);
+}
+
+Value *Value::stripPointerCastsNoFollowAliases() {
   return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
 }
 

Modified: llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp?rev=181175&r1=181174&r2=181175&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp Sun May  5 20:48:55 2013
@@ -27,6 +27,7 @@
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
 #include "llvm/Pass.h"
 using namespace llvm;
 
@@ -68,10 +69,11 @@ static void FindUsedValues(GlobalVariabl
   if (LLVMUsed == 0) return;
   ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
 
-  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
-    if (GlobalValue *GV = 
-        dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
-      UsedValues.insert(GV);
+  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) {
+    Value *Operand = Inits->getOperand(i)->stripPointerCastsNoFollowAliases();
+    GlobalValue *GV = cast<GlobalValue>(Operand);
+    UsedValues.insert(GV);
+  }
 }
 
 // True if A is better than B.

Modified: llvm/trunk/test/Transforms/ConstantMerge/merge-both.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstantMerge/merge-both.ll?rev=181175&r1=181174&r2=181175&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/ConstantMerge/merge-both.ll (original)
+++ llvm/trunk/test/Transforms/ConstantMerge/merge-both.ll Sun May  5 20:48:55 2013
@@ -26,6 +26,9 @@ declare void @helper([16 x i8]*)
 ; CHECK-NEXT: @var6 = private constant [16 x i8] c"foo1bar2foo3bar\00", align 16
 ; CHECK-NEXT: @var8 = private constant [16 x i8] c"foo1bar2foo3bar\00"
 
+ at var4a = alias %struct.foobar* @var4
+ at llvm.used = appending global [1 x %struct.foobar*] [%struct.foobar* @var4a], section "llvm.metadata"
+
 define i32 @main() {
 entry:
   call void @zed(%struct.foobar* @var1, %struct.foobar* @var2)





More information about the llvm-commits mailing list