diff options
author | Chris Lattner <sabre@nondot.org> | 2006-03-08 01:05:29 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-03-08 01:05:29 +0000 |
commit | 25de486263abc1882498a8701e3eb29ee0804c4e (patch) | |
tree | 6bd6ba3c8dea02d95587400064f4b35f5f759293 | |
parent | 49f398b96a026034c2e92ffeca692d0f57fa771a (diff) |
Fix a miscompilation of 188.ammp with the new CFE. 188.ammp is accessing
arrays out of range in a horrible way, but we shouldn't break it anyway.
Details in the comments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26606 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/ScalarReplAggregates.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 001f3a5732..f3c163d76a 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -289,7 +289,7 @@ int SROA::isSafeUseOfAllocation(Instruction *User) { GetElementPtrInst *GEPI = cast<GetElementPtrInst>(User); gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI); - // The GEP is safe to transform if it is of the form GEP <ptr>, 0, <cst> + // The GEP is not safe to transform if not of the form "GEP <ptr>, 0, <cst>". if (I == E || I.getOperand() != Constant::getNullValue(I.getOperand()->getType())) return 0; @@ -308,13 +308,29 @@ int SROA::isSafeUseOfAllocation(Instruction *User) { if (cast<ConstantInt>(GEPI->getOperand(2))->getRawValue() >= NumElements) return 0; + // We cannot scalar repl this level of the array unless any array + // sub-indices are in-range constants. In particular, consider: + // A[0][i]. We cannot know that the user isn't doing invalid things like + // allowing i to index an out-of-range subscript that accesses A[1]. + // + // Scalar replacing *just* the outer index of the array is probably not + // going to be a win anyway, so just give up. + for (++I; I != E && isa<ArrayType>(*I); ++I) { + const ArrayType *SubArrayTy = cast<ArrayType>(*I); + uint64_t NumElements = SubArrayTy->getNumElements(); + if (!isa<ConstantInt>(I.getOperand())) return 0; + if (cast<ConstantInt>(I.getOperand())->getRawValue() >= NumElements) + return 0; + } + } else { // If this is an array index and the index is not constant, we cannot // promote... that is unless the array has exactly one or two elements in // it, in which case we CAN promote it, but we have to canonicalize this // out if this is the only problem. - if (NumElements == 1 || NumElements == 2) - return AllUsersAreLoads(GEPI) ? 1 : 0; // Canonicalization required! + if ((NumElements == 1 || NumElements == 2) && + AllUsersAreLoads(GEPI)) + return 1; // Canonicalization required! return 0; } } |