diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2020-11-06 14:14:46 -0500 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2020-11-06 14:20:54 -0500 |
commit | 129e1a8a96d140150705fab30d25afb464eb1d99 (patch) | |
tree | 07ad6c227d61e224f8495143c81292a079db91fe /gcc | |
parent | 25126a28dbea7f9c7d6e5365929d7f3c9f60cdaf (diff) | |
download | gcc-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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range.cc | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr97737.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr97741.c | 17 |
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; } |