diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2012-09-25 10:03:40 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2012-09-25 10:03:40 +0000 |
commit | c303463dcceb6a3b15e6f4d11d7c31c1ac2ce276 (patch) | |
tree | 39c283ce8ddbc51a15c1d9b2a2670e25c7ac3ed7 /lib/Transforms | |
parent | 00edf4c1d8a691543faf5adf7b05558497d38abb (diff) | |
download | external_llvm-c303463dcceb6a3b15e6f4d11d7c31c1ac2ce276.zip external_llvm-c303463dcceb6a3b15e6f4d11d7c31c1ac2ce276.tar.gz external_llvm-c303463dcceb6a3b15e6f4d11d7c31c1ac2ce276.tar.bz2 |
Fix a case where SROA did not correctly detect dead PHI or selects due
to chains or cycles between PHIs and/or selects. Also add a couple of
really nice test cases reduced from Kostya's reports in PR13905 and
PR13906. Both are fixed by this patch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164596 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/SROA.cpp | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index dbda627..b3e63ae 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -522,8 +522,10 @@ private: void insertUse(Instruction &I, int64_t Offset, uint64_t Size, bool IsSplittable = false) { - // Completely skip uses which don't overlap the allocation. - if ((Offset >= 0 && (uint64_t)Offset >= AllocSize) || + // Completely skip uses which have a zero size or don't overlap the + // allocation. + if (Size == 0 || + (Offset >= 0 && (uint64_t)Offset >= AllocSize) || (Offset < 0 && (uint64_t)-Offset >= Size)) { DEBUG(dbgs() << "WARNING: Ignoring " << Size << " byte use @" << Offset << " which starts past the end of the " << AllocSize @@ -697,6 +699,9 @@ private: SmallVector<std::pair<Instruction *, Instruction *>, 4> Uses; Visited.insert(Root); Uses.push_back(std::make_pair(cast<Instruction>(*U), Root)); + // If there are no loads or stores, the access is dead. We mark that as + // a size zero access. + Size = 0; do { Instruction *I, *UsedI; llvm::tie(UsedI, I) = Uses.pop_back_val(); @@ -824,9 +829,9 @@ private: } void insertUse(Instruction &User, int64_t Offset, uint64_t Size) { - // If the use extends outside of the allocation, record it as a dead use - // for elimination later. - if ((uint64_t)Offset >= AllocSize || + // If the use has a zero size or extends outside of the allocation, record + // it as a dead use for elimination later. + if (Size == 0 || (uint64_t)Offset >= AllocSize || (Offset < 0 && (uint64_t)-Offset >= Size)) return markAsDead(User); |