From 129e1a8a96d140150705fab30d25afb464eb1d99 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Fri, 6 Nov 2020 14:14:46 -0500 Subject: [PATCH] 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. --- gcc/gimple-range.cc | 10 ++++++++-- gcc/testsuite/gcc.dg/pr97737.c | 16 ++++++++++++++++ gcc/testsuite/gcc.dg/pr97741.c | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr97737.c create mode 100644 gcc/testsuite/gcc.dg/pr97741.c diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 0c8ec40448f..92a6335bec5 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 00000000000..eef1c353191 --- /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 00000000000..47115d31d4a --- /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; } -- 2.30.2