diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-09-20 23:28:51 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-09-20 23:28:51 +0000 |
commit | 79782fc8649e081b59fe2f96265042eaec1542a7 (patch) | |
tree | c02f594c33d6dd57ee8382490e31e7eaa2bc7c44 /lib/Transforms | |
parent | e97190fdf875843e8161a942f2046fd3ef81330f (diff) | |
download | llvm-79782fc8649e081b59fe2f96265042eaec1542a7.tar.gz llvm-79782fc8649e081b59fe2f96265042eaec1542a7.tar.bz2 llvm-79782fc8649e081b59fe2f96265042eaec1542a7.tar.xz |
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 02e6b72d3a..196a847fc0 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -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. |