mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 04:32:19 +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,16 +1433,26 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
|
|||||||
if (I->getType()->isVoidTy()) continue;
|
if (I->getType()->isVoidTy()) continue;
|
||||||
|
|
||||||
if (StructType *STy = dyn_cast<StructType>(I->getType())) {
|
if (StructType *STy = dyn_cast<StructType>(I->getType())) {
|
||||||
// Only a few things that can be structs matter for undef. Just send
|
// Only a few things that can be structs matter for undef.
|
||||||
// all their results to overdefined. We could be more precise than this
|
|
||||||
// but it isn't worth bothering.
|
// Tracked calls must never be marked overdefined in ResolvedUndefsIn.
|
||||||
if (!isa<ExtractValueInst>(I) && !isa<InsertValueInst>(I)) {
|
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) {
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
||||||
LatticeVal &LV = getStructValueState(I, i);
|
LatticeVal &LV = getStructValueState(I, i);
|
||||||
if (LV.isUndefined())
|
if (LV.isUndefined())
|
||||||
markOverdefined(LV, I);
|
markOverdefined(LV, I);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1594,6 +1604,22 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
|
|||||||
break;
|
break;
|
||||||
markOverdefined(I);
|
markOverdefined(I);
|
||||||
return true;
|
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:
|
default:
|
||||||
// If we don't know what should happen here, conservatively mark it
|
// If we don't know what should happen here, conservatively mark it
|
||||||
// overdefined.
|
// overdefined.
|
||||||
|
@ -209,3 +209,21 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @__gxx_personality_v0(...)
|
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…
x
Reference in New Issue
Block a user