Check for undefined before not returning a constant value

Don't return UNDEFINED for a range in an unreachable block if the global
value evaluates to a constant.  Return that constant instead.

	PR tree-optimization/97515
	* value-query.cc (range_query::value_of_expr): If the result is
	UNDEFINED, check to see if the global value is a constant.
	(range_query::value_on_edge): Ditto.
This commit is contained in:
Andrew MacLeod 2020-10-21 19:55:28 -04:00
parent 2ab1fc7a32
commit ca5f4666f7
2 changed files with 40 additions and 4 deletions

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
int
e7 (int gg)
{
int xe = 0;
while (xe < 1)
{
int ui;
ui = ~xe;
if (ui == 0)
ui = xe >> gg;
xe %= !ui;
}
return xe;
}

View File

@ -82,8 +82,16 @@ range_query::value_of_expr (tree name, gimple *stmt)
if (!irange::supports_type_p (TREE_TYPE (name)))
return NULL_TREE;
if (range_of_expr (r, name, stmt) && r.singleton_p (&t))
if (range_of_expr (r, name, stmt))
{
// A constant used in an unreachable block oftens returns as UNDEFINED.
// If the result is undefined, check the global value for a constant.
if (r.undefined_p ())
range_of_expr (r, name);
if (r.singleton_p (&t))
return t;
}
return NULL_TREE;
}
@ -95,8 +103,15 @@ range_query::value_on_edge (edge e, tree name)
if (!irange::supports_type_p (TREE_TYPE (name)))
return NULL_TREE;
if (range_on_edge (r, e, name) && r.singleton_p (&t))
if (range_on_edge (r, e, name))
{
// A constant used in an unreachable block oftens returns as UNDEFINED.
// If the result is undefined, check the global value for a constant.
if (r.undefined_p ())
range_of_expr (r, name);
if (r.singleton_p (&t))
return t;
}
return NULL_TREE;
}