From dfd3102f8efd0a1f21aa901e1f551012769ffb20 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 3 Dec 2012 10:59:55 +0000 Subject: [PATCH] Remove some buggy and apparantly unnecessary code from SROA. The partitioning logic attempted to handle uses of an alloca with an offset starting before the alloca so long as the use had some overlap with the alloca itself. However, there was a bug where we tested '(uint64_t)Offset >= AllocSize' without first checking whether 'Offset' was positive. As a consequence, essentially every negative offset (that is, starting *before* the alloca does) would be thrown out, even if it was overlapping. The subsequent code to throw out negative offsets which were actually non-overlapping was essentially dead. The code to *handle* overlapping negative offsets was actually dead! I've just removed all of this, and taught SROA to discard any uses which start prior to the alloca from the beginning. It has the lovely property of simplifying the code. =] All the tests still pass, and in fact no new tests are needed as this is already covered by our testsuite. Fixing the code so that negative offsets work the way the comments indicate they were supposed to work causes regressions. That's how I found this. Anyways, this is all progress in the correct direction -- tightening up SROA to be maximally aggressive. Some day, I really hope to turn out-of-bounds accesses to an alloca into 'unreachable'. llvm-svn: 169120 --- lib/Transforms/Scalar/SROA.cpp | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 68d5d3f01a0..6277877f4ba 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -541,29 +541,17 @@ private: void insertUse(Instruction &I, int64_t Offset, uint64_t Size, bool IsSplittable = false) { - // 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)) { + // Completely skip uses which have a zero size or start either before or + // past the end of the allocation. + if (Size == 0 || Offset < 0 || (uint64_t)Offset >= AllocSize) { DEBUG(dbgs() << "WARNING: Ignoring " << Size << " byte use @" << Offset - << " which starts past the end of the " << AllocSize - << " byte alloca:\n" + << " which has zero size or starts outside of the " + << AllocSize << " byte alloca:\n" << " alloca: " << P.AI << "\n" << " use: " << I << "\n"); return; } - // Clamp the start to the beginning of the allocation. - if (Offset < 0) { - DEBUG(dbgs() << "WARNING: Clamping a " << Size << " byte use @" << Offset - << " to start at the beginning of the alloca:\n" - << " alloca: " << P.AI << "\n" - << " use: " << I << "\n"); - Size -= (uint64_t)-Offset; - Offset = 0; - } - uint64_t BeginOffset = Offset, EndOffset = BeginOffset + Size; // Clamp the end offset to the end of the allocation. Note that this is @@ -881,16 +869,9 @@ private: void insertUse(Instruction &User, int64_t Offset, uint64_t Size) { // 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)) + if (Size == 0 || Offset < 0 || (uint64_t)Offset >= AllocSize) return markAsDead(User); - // Clamp the start to the beginning of the allocation. - if (Offset < 0) { - Size -= (uint64_t)-Offset; - Offset = 0; - } - uint64_t BeginOffset = Offset, EndOffset = BeginOffset + Size; // Clamp the end offset to the end of the allocation. Note that this is