summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-05-06 01:48:55 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-05-06 01:48:55 +0000
commitc229a4fff4f5814e761fa6153408a3d28a0c539e (patch)
tree4922a756eb50cae63c14644f7104049095c9983b
parentd74b1606a6b5fc3913f815773e2c2955943b33cd (diff)
downloadbcm5719-llvm-c229a4fff4f5814e761fa6153408a3d28a0c539e.tar.gz
bcm5719-llvm-c229a4fff4f5814e761fa6153408a3d28a0c539e.zip
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. llvm-svn: 181175
-rw-r--r--llvm/include/llvm/IR/Value.h16
-rw-r--r--llvm/lib/IR/Value.cpp8
-rw-r--r--llvm/lib/Transforms/IPO/ConstantMerge.cpp10
-rw-r--r--llvm/test/Transforms/ConstantMerge/merge-both.ll3
4 files changed, 29 insertions, 8 deletions
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index fb61a2ac70d..5fba3d57144 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -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
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index e9eb012e6ce..89a3c0578cf 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -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 *stripPointerCastsAndOffsets(Value *V) {
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 *stripPointerCastsAndOffsets(Value *V) {
} 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 *stripPointerCastsAndOffsets(Value *V) {
} // namespace
Value *Value::stripPointerCasts() {
+ return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this);
+}
+
+Value *Value::stripPointerCastsNoFollowAliases() {
return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
}
diff --git a/llvm/lib/Transforms/IPO/ConstantMerge.cpp b/llvm/lib/Transforms/IPO/ConstantMerge.cpp
index b63495b9685..a7bf18896b5 100644
--- a/llvm/lib/Transforms/IPO/ConstantMerge.cpp
+++ b/llvm/lib/Transforms/IPO/ConstantMerge.cpp
@@ -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(GlobalVariable *LLVMUsed,
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.
diff --git a/llvm/test/Transforms/ConstantMerge/merge-both.ll b/llvm/test/Transforms/ConstantMerge/merge-both.ll
index b00345557c8..316267648f1 100644
--- a/llvm/test/Transforms/ConstantMerge/merge-both.ll
+++ b/llvm/test/Transforms/ConstantMerge/merge-both.ll
@@ -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"
+@var4a = alias %struct.foobar* @var4
+@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)
OpenPOWER on IntegriCloud