aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-11-01 15:08:32 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-11-01 15:08:32 +0000
commit7fc53ba4f8a0cecb7288ae04e32dfb38af016f57 (patch)
tree9c618068ee20724e4f1389cc95ec28e28dafdb0a
parentcb8e3dda35164dcb85056556779daa673b40166a (diff)
downloadgcc-7fc53ba4f8a0cecb7288ae04e32dfb38af016f57.zip
gcc-7fc53ba4f8a0cecb7288ae04e32dfb38af016f57.tar.gz
gcc-7fc53ba4f8a0cecb7288ae04e32dfb38af016f57.tar.bz2
Don't treat zero-sized ranges as overlapping
Most GCC ranges seem to be represented as an offset and a size (rather than a start and inclusive end or start and exclusive end). The usual test for whether X is in a range is of course: x >= start && x < start + size or: x >= start && x - start < size which means that an empty range of size 0 contains nothing. But other range tests aren't as obvious. The usual test for whether one range is contained within another range is: start1 >= start2 && start1 + size1 <= start2 + size2 while the test for whether two ranges overlap (from ranges_overlap_p) is: (start1 >= start2 && start1 < start2 + size2) || (start2 >= start1 && start2 < start1 + size1) i.e. the ranges overlap if one range contains the start of the other range. This leads to strange results like: (start X, size 0) is a subrange of (start X, size 0) but (start X, size 0) does not overlap (start X, size 0) Similarly: (start 4, size 0) is a subrange of (start 2, size 2) but (start 4, size 0) does not overlap (start 2, size 2) It seems like "X is a subrange of Y" should imply "X overlaps Y". This becomes harder to ignore with the runtime sizes and offsets added for SVE. The most obvious fix seemed to be to say that an empty range does not overlap anything, and is therefore not a subrange of anything. Using the new definition of subranges didn't seem to cause any codegen differences in the testsuite. But there was one change with the new definition of overlapping ranges. strncpy-chk.c has: memset (dst, 0, sizeof (dst)); if (strncpy (dst, src, 0) != dst || strcmp (dst, "")) abort(); The strncpy is detected as a zero-size write, and so with the new definition of overlapping ranges, we treat the strncpy as having no effect on the strcmp (which is true). The reaching definition is the memset instead. This patch makes ranges_overlap_p return false for zero-sized ranges, even if the other range has an unknown size. 2017-11-01 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * tree-ssa-alias.h (ranges_overlap_p): Return false if either range is known to be empty. From-SVN: r254312
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/tree-ssa-alias.h2
2 files changed, 7 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8cf72e6..a90d258 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,9 @@
2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * tree-ssa-alias.h (ranges_overlap_p): Return false if either
+ range is known to be empty.
+
+2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 8c89c69..c52ed3f 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -171,6 +171,8 @@ ranges_overlap_p (HOST_WIDE_INT pos1,
HOST_WIDE_INT pos2,
unsigned HOST_WIDE_INT size2)
{
+ if (size1 == 0 || size2 == 0)
+ return false;
if (pos1 >= pos2
&& (size2 == (unsigned HOST_WIDE_INT)-1
|| pos1 < (pos2 + (HOST_WIDE_INT) size2)))