[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