aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2020-11-06 14:14:46 -0500
committerAndrew MacLeod <amacleod@redhat.com>2020-11-06 14:20:54 -0500
commit129e1a8a96d140150705fab30d25afb464eb1d99 (patch)
tree07ad6c227d61e224f8495143c81292a079db91fe
parent25126a28dbea7f9c7d6e5365929d7f3c9f60cdaf (diff)
downloadgcc-129e1a8a96d140150705fab30d25afb464eb1d99.zip
gcc-129e1a8a96d140150705fab30d25afb464eb1d99.tar.gz
gcc-129e1a8a96d140150705fab30d25afb464eb1d99.tar.bz2
Combine new calculated ranges with existing range.
When a range is recalculated, retain what was previously known as IL changes can produce different results from un-executed code. This also paves the way for external injection of ranges. gcc/ PR tree-optimization/97737 PR tree-optimization/97741 * gimple-range.cc: (gimple_ranger::range_of_stmt): Intersect newly calculated ranges with the existing known global range. gcc/testsuite/ * gcc.dg/pr97737.c: New. * gcc.dg/pr97741.c: New.
-rw-r--r--gcc/gimple-range.cc10
-rw-r--r--gcc/testsuite/gcc.dg/pr97737.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr97741.c17
3 files changed, 41 insertions, 2 deletions
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 0c8ec40..92a6335 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -1026,8 +1026,14 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
if (m_cache.get_non_stale_global_range (r, name))
return true;
- // Otherwise calculate a new value and save it.
- calc_stmt (r, s, name);
+ // Otherwise calculate a new value.
+ int_range_max tmp;
+ calc_stmt (tmp, s, name);
+
+ // Combine the new value with the old value. This is required because
+ // the way value propagation works, when the IL changes on the fly we
+ // can sometimes get different results. See PR 97741.
+ r.intersect (tmp);
m_cache.set_global_range (name, r);
return true;
}
diff --git a/gcc/testsuite/gcc.dg/pr97737.c b/gcc/testsuite/gcc.dg/pr97737.c
new file mode 100644
index 0000000..eef1c35
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97737.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int a = 1, b, c;
+
+void d() {
+ int e = 1;
+L1:
+ b = e;
+L2:
+ e = e / a;
+ if (!(e || c || e - 1))
+ goto L1;
+ if (!b)
+ goto L2;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97741.c b/gcc/testsuite/gcc.dg/pr97741.c
new file mode 100644
index 0000000..47115d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97741.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -Wextra -fno-strict-aliasing -fwrapv -Os -fno-toplevel-reorder -fno-tree-ccp -fno-tree-fre" } */
+
+short a = 0;
+long b = 0;
+char c = 0;
+void d() {
+ int e = 0;
+f:
+ for (a = 6; a;)
+ c = e;
+ e = 0;
+ for (; e == 20; ++e)
+ for (; b;)
+ goto f;
+}
+int main() { return 0; }