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).

llvm-svn: 151093
This commit is contained in:
Nick Lewycky 2012-02-21 22:08:06 +00:00
parent 286e0e0818
commit 9d0da18597
2 changed files with 52 additions and 2 deletions

View File

@ -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,6 +2425,8 @@ 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.
@ -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.

View File

@ -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 }]