mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
Make sure IPSCCP never marks a tracked call as overdefined in SCCPSolver::ResolvedUndefsIn. If we do, we can end up in a situation where a function is resolved to return a constant, but the caller is marked overdefined, which confuses the code later.
<rdar://problem/9956541> (again). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140210 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e97190fdf8
commit
79782fc864
@ -1433,15 +1433,25 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
|
||||
if (I->getType()->isVoidTy()) continue;
|
||||
|
||||
if (StructType *STy = dyn_cast<StructType>(I->getType())) {
|
||||
// Only a few things that can be structs matter for undef. Just send
|
||||
// all their results to overdefined. We could be more precise than this
|
||||
// but it isn't worth bothering.
|
||||
if (!isa<ExtractValueInst>(I) && !isa<InsertValueInst>(I)) {
|
||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
||||
LatticeVal &LV = getStructValueState(I, i);
|
||||
if (LV.isUndefined())
|
||||
markOverdefined(LV, I);
|
||||
}
|
||||
// Only a few things that can be structs matter for undef.
|
||||
|
||||
// Tracked calls must never be marked overdefined in ResolvedUndefsIn.
|
||||
if (CallSite CS = CallSite(I))
|
||||
if (Function *F = CS.getCalledFunction())
|
||||
if (MRVFunctionsTracked.count(F))
|
||||
continue;
|
||||
|
||||
// extractvalue and insertvalue don't need to be marked; they are
|
||||
// tracked as precisely as their operands.
|
||||
if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(I))
|
||||
continue;
|
||||
|
||||
// Send the results of everything else to overdefined. We could be
|
||||
// more precise than this but it isn't worth bothering.
|
||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
||||
LatticeVal &LV = getStructValueState(I, i);
|
||||
if (LV.isUndefined())
|
||||
markOverdefined(LV, I);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -1594,6 +1604,22 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
|
||||
break;
|
||||
markOverdefined(I);
|
||||
return true;
|
||||
case Instruction::Call:
|
||||
case Instruction::Invoke: {
|
||||
// There are two reasons a call can have an undef result
|
||||
// 1. It could be tracked.
|
||||
// 2. It could be constant-foldable.
|
||||
// Because of the way we solve return values, tracked calls must
|
||||
// never be marked overdefined in ResolvedUndefsIn.
|
||||
if (Function *F = CallSite(I).getCalledFunction())
|
||||
if (TrackedRetVals.count(F))
|
||||
break;
|
||||
|
||||
// If the call is constant-foldable, we mark it overdefined because
|
||||
// we do not know what return values are valid.
|
||||
markOverdefined(I);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// If we don't know what should happen here, conservatively mark it
|
||||
// overdefined.
|
||||
|
@ -209,3 +209,21 @@ entry:
|
||||
}
|
||||
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
;;======================== test10
|
||||
|
||||
define i32 @test10a() nounwind {
|
||||
entry:
|
||||
%call = call i32 @test10b(i32 undef)
|
||||
ret i32 %call
|
||||
; CHECK: define i32 @test10a
|
||||
; CHECK: ret i32 0
|
||||
}
|
||||
|
||||
define internal i32 @test10b(i32 %x) nounwind {
|
||||
entry:
|
||||
%r = and i32 %x, 1
|
||||
ret i32 %r
|
||||
; CHECK: define internal i32 @test10b
|
||||
; CHECK: ret i32 undef
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user