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.
This commit is contained in:
Andrew MacLeod 2020-11-06 14:14:46 -05:00
parent 25126a28db
commit 129e1a8a96
3 changed files with 41 additions and 2 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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; }