diff options
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 11 | ||||
-rw-r--r-- | test/Transforms/GlobalOpt/constantfold-initializers.ll | 43 |
2 files changed, 52 insertions, 2 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index bb37bf4..7c78a20 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 834bd00..af8fa32 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 }] |