[llvm-commits] [llvm] r147625 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
Eli Friedman
eli.friedman at gmail.com
Thu Jan 5 15:03:32 PST 2012
Author: efriedma
Date: Thu Jan 5 17:03:32 2012
New Revision: 147625
URL: http://llvm.org/viewvc/llvm-project?rev=147625&view=rev
Log:
PR11705, part 2: globalopt shouldn't put inttoptr/ptrtoint operations into global initializers if there's an implied extension or truncation.
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=147625&r1=147624&r2=147625&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Jan 5 17:03:32 2012
@@ -2069,7 +2069,8 @@
static inline bool
isSimpleEnoughValueToCommit(Constant *C,
- SmallPtrSet<Constant*, 8> &SimpleConstants);
+ SmallPtrSet<Constant*, 8> &SimpleConstants,
+ const TargetData *TD);
/// isSimpleEnoughValueToCommit - Return true if the specified constant can be
@@ -2081,7 +2082,8 @@
/// in SimpleConstants to avoid having to rescan the same constants all the
/// time.
static bool isSimpleEnoughValueToCommitHelper(Constant *C,
- SmallPtrSet<Constant*, 8> &SimpleConstants) {
+ SmallPtrSet<Constant*, 8> &SimpleConstants,
+ const TargetData *TD) {
// Simple integer, undef, constant aggregate zero, global addresses, etc are
// all supported.
if (C->getNumOperands() == 0 || isa<BlockAddress>(C) ||
@@ -2093,7 +2095,7 @@
isa<ConstantVector>(C)) {
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
Constant *Op = cast<Constant>(C->getOperand(i));
- if (!isSimpleEnoughValueToCommit(Op, SimpleConstants))
+ if (!isSimpleEnoughValueToCommit(Op, SimpleConstants, TD))
return false;
}
return true;
@@ -2105,34 +2107,42 @@
ConstantExpr *CE = cast<ConstantExpr>(C);
switch (CE->getOpcode()) {
case Instruction::BitCast:
+ // Bitcast is fine if the casted value is fine.
+ return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, TD);
+
case Instruction::IntToPtr:
case Instruction::PtrToInt:
- // These casts are always fine if the casted value is.
- return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants);
+ // int <=> ptr is fine if the int type is the same size as the
+ // pointer type.
+ if (!TD || TD->getTypeSizeInBits(CE->getType()) !=
+ TD->getTypeSizeInBits(CE->getOperand(0)->getType()))
+ return false;
+ return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, TD);
// GEP is fine if it is simple + constant offset.
case Instruction::GetElementPtr:
for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
if (!isa<ConstantInt>(CE->getOperand(i)))
return false;
- return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants);
+ return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, TD);
case Instruction::Add:
// We allow simple+cst.
if (!isa<ConstantInt>(CE->getOperand(1)))
return false;
- return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants);
+ return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, TD);
}
return false;
}
static inline bool
isSimpleEnoughValueToCommit(Constant *C,
- SmallPtrSet<Constant*, 8> &SimpleConstants) {
+ SmallPtrSet<Constant*, 8> &SimpleConstants,
+ const TargetData *TD) {
// If we already checked this constant, we win.
if (!SimpleConstants.insert(C)) return true;
// Check the constant.
- return isSimpleEnoughValueToCommitHelper(C, SimpleConstants);
+ return isSimpleEnoughValueToCommitHelper(C, SimpleConstants, TD);
}
@@ -2353,7 +2363,7 @@
// If this might be too difficult for the backend to handle (e.g. the addr
// of one global variable divided by another) then we can't commit it.
- if (!isSimpleEnoughValueToCommit(Val, SimpleConstants))
+ if (!isSimpleEnoughValueToCommit(Val, SimpleConstants, TD))
return false;
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
Modified: llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll?rev=147625&r1=147624&r2=147625&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll (original)
+++ llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll Thu Jan 5 17:03:32 2012
@@ -4,20 +4,31 @@
%0 = type { i32, void ()* }
%struct.foo = type { i32* }
+%struct.bar = type { i128 }
@G = global i32 0, align 4
@H = global i32 0, align 4
@X = global %struct.foo zeroinitializer, align 8
- at llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @init }]
+ at X2 = global %struct.bar zeroinitializer, align 8
+ at llvm.global_ctors = appending global [2 x %0] [%0 { i32 65535, void ()* @init1 }, %0 { i32 65535, void ()* @init2 }]
; PR8710 - GlobalOpt shouldn't change the global's initializer to have this
; arbitrary constant expression, the code generator can't handle it.
-define internal void @init() {
+define internal void @init1() {
entry:
%tmp = getelementptr inbounds %struct.foo* @X, i32 0, i32 0
store i32* inttoptr (i64 sdiv (i64 ptrtoint (i32* @G to i64), i64 ptrtoint (i32* @H to i64)) to i32*), i32** %tmp, align 8
ret void
}
-
-; CHECK: @init
+; CHECK: @init1
; CHECK: store i32*
+
+; PR11705 - ptrtoint isn't safe in general in global initializers.
+define internal void @init2() {
+entry:
+ %tmp = getelementptr inbounds %struct.bar* @X2, i32 0, i32 0
+ store i128 ptrtoint (i32* @G to i128), i128* %tmp, align 16
+ ret void
+}
+; CHECK: @init2
+; CHECK: store i128
More information about the llvm-commits
mailing list