Fix PR14132 and handle OOB loads speculated throuh PHI nodes.

The issue is that we may end up with newly OOB loads when speculating
a load into the predecessors of a PHI node, and this confuses the new
integer splitting logic in some cases, triggering an assertion failure.
In fact, the branch in question must be dead code as it loads from
a too-narrow alloca. Add code to handle this gracefully and leave the
requisite FIXMEs for both optimizing more aggressively and doing more to
aid sanitizing invalid code which triggers these patterns.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168361 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth
2012-11-20 10:02:19 +00:00
parent 310f248c22
commit 176792990e
2 changed files with 56 additions and 0 deletions

View File

@ -568,6 +568,10 @@ private:
// Clamp the end offset to the end of the allocation. Note that this is
// formulated to handle even the case where "BeginOffset + Size" overflows.
// NOTE! This may appear superficially to be something we could ignore
// entirely, but that is not so! There may be PHI-node uses where some
// instructions are dead but not others. We can't completely ignore the
// PHI node, and so have to record at least the information here.
assert(AllocSize >= BeginOffset); // Established above.
if (Size > AllocSize - BeginOffset) {
DEBUG(dbgs() << "WARNING: Clamping a " << Size << " byte use @" << Offset
@ -2492,6 +2496,23 @@ private:
uint64_t Size = EndOffset - BeginOffset;
bool IsSplitIntLoad = Size < TD.getTypeStoreSize(LI.getType());
// If this memory access can be shown to *statically* extend outside the
// bounds of the original allocation it's behavior is undefined. Rather
// than trying to transform it, just replace it with undef.
// FIXME: We should do something more clever for functions being
// instrumented by asan.
// FIXME: Eventually, once ASan and friends can flush out bugs here, this
// should be transformed to a load of null making it unreachable.
uint64_t OldAllocSize = TD.getTypeAllocSize(OldAI.getAllocatedType());
if (TD.getTypeStoreSize(LI.getType()) > OldAllocSize) {
LI.replaceAllUsesWith(UndefValue::get(LI.getType()));
Pass.DeadInsts.insert(&LI);
deleteIfTriviallyDead(OldOp);
DEBUG(dbgs() << " to: undef!!\n");
return true;
}
Type *TargetTy = IsSplitIntLoad ? Type::getIntNTy(LI.getContext(), Size * 8)
: LI.getType();
bool IsPtrAdjusted = false;