summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2012-02-21 22:08:06 +0000
committerNick Lewycky <nicholas@mxc.ca>2012-02-21 22:08:06 +0000
commita641c07828fe4e836d680b9e8b0b4af3204b8b97 (patch)
tree476b174150c55bfa16af796808c71dd4a2554dd0
parent07043279f60622243d16d8a3f60805960482083c (diff)
downloadllvm-a641c07828fe4e836d680b9e8b0b4af3204b8b97.tar.gz
llvm-a641c07828fe4e836d680b9e8b0b4af3204b8b97.tar.bz2
llvm-a641c07828fe4e836d680b9e8b0b4af3204b8b97.tar.xz
Use the target-aware constant folder on expressions to improve the chance
they'll be simple enough to simulate, and to reduce the chance we'll encounter equal but different simple pointer constants. This removes the symptoms from PR11352 but is not a full fix. A proper fix would either require a guarantee that two constant objects we simulate are folded when equal, or a different way of handling equal pointers (ie., trying a constantexpr icmp on them to see whether we know they're equal or non-equal or unsure). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151093 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp11
-rw-r--r--test/Transforms/GlobalOpt/constantfold-initializers.ll43
2 files changed, 52 insertions, 2 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index bb37bf4c26..7c78a20544 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -2388,6 +2388,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
if (StoreInst *SI = dyn_cast<StoreInst>(CurInst)) {
if (!SI->isSimple()) return false; // no volatile/atomic accesses.
Constant *Ptr = getVal(SI->getOperand(1));
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
+ Ptr = ConstantFoldConstantExpression(CE, TD, TLI);
if (!isSimpleEnoughPointerToCommit(Ptr))
// If this is too complex for us to commit, reject it.
return false;
@@ -2423,7 +2425,9 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
Constant * const IdxList[] = {IdxZero, IdxZero};
Ptr = ConstantExpr::getGetElementPtr(Ptr, IdxList);
-
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
+ Ptr = ConstantFoldConstantExpression(CE, TD, TLI);
+
// If we can't improve the situation by introspecting NewTy,
// we have to give up.
} else {
@@ -2464,7 +2468,10 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
cast<GEPOperator>(GEP)->isInBounds());
} else if (LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {
if (!LI->isSimple()) return false; // no volatile/atomic accesses.
- InstResult = ComputeLoadResult(getVal(LI->getOperand(0)));
+ Constant *Ptr = getVal(LI->getOperand(0));
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
+ Ptr = ConstantFoldConstantExpression(CE, TD, TLI);
+ InstResult = ComputeLoadResult(Ptr);
if (InstResult == 0) return false; // Could not evaluate load.
} else if (AllocaInst *AI = dyn_cast<AllocaInst>(CurInst)) {
if (AI->isArrayAllocation()) return false; // Cannot handle array allocs.
diff --git a/test/Transforms/GlobalOpt/constantfold-initializers.ll b/test/Transforms/GlobalOpt/constantfold-initializers.ll
index 834bd0012e..af8fa324db 100644
--- a/test/Transforms/GlobalOpt/constantfold-initializers.ll
+++ b/test/Transforms/GlobalOpt/constantfold-initializers.ll
@@ -6,3 +6,46 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; CHECK: @A = global i1 false
@A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1)
+
+; PR11352
+
+@xs = global [2 x i32] zeroinitializer, align 4
+; CHECK: @xs = global [2 x i32] [i32 1, i32 1]
+
+define internal void @test1() {
+entry:
+ store i32 1, i32* getelementptr inbounds ([2 x i32]* @xs, i64 0, i64 0)
+ %0 = load i32* getelementptr inbounds ([2 x i32]* @xs, i32 0, i64 0), align 4
+ store i32 %0, i32* getelementptr inbounds ([2 x i32]* @xs, i64 0, i64 1)
+ ret void
+}
+
+; PR12060
+
+%closure = type { i32 }
+
+@f = internal global %closure zeroinitializer, align 4
+@m = global i32 0, align 4
+; CHECK-NOT: @f
+; CHECK: @m = global i32 13
+
+define internal i32 @test2_helper(%closure* %this, i32 %b) {
+entry:
+ %0 = getelementptr inbounds %closure* %this, i32 0, i32 0
+ %1 = load i32* %0, align 4
+ %add = add nsw i32 %1, %b
+ ret i32 %add
+}
+
+define internal void @test2() {
+entry:
+ store i32 4, i32* getelementptr inbounds (%closure* @f, i32 0, i32 0)
+ %call = call i32 @test2_helper(%closure* @f, i32 9)
+ store i32 %call, i32* @m, align 4
+ ret void
+}
+
+@llvm.global_ctors = appending constant
+ [2 x { i32, void ()* }]
+ [{ i32, void ()* } { i32 65535, void ()* @test1 },
+ { i32, void ()* } { i32 65535, void ()* @test2 }]