diff mbox series

Check for undefined before not returning a constant value

Message ID 49d2b4a4-5be6-66ac-77d1-25523cac092a@redhat.com
State New
Headers show
Series Check for undefined before not returning a constant value | expand

Commit Message

Andrew MacLeod Oct. 22, 2020, 12:04 a.m. UTC
Full comments in the PR, but basically substitute and fold was expecting 
to see a constant returned for any range which globally evaluates to a 
constant.
This allowed it to replace all uses of an ssa name as they were encountered.

The ranger model can return UNDEFINED for the range of names in blocks 
which are unreachable..  the patch simply overrides the UNDEFINED value 
in folders query if the global value is a constant so that 
subst_and_fold will get what it is expecting.

Bootstrapped on  x86_64-pc-linux-gnu, no regressions, pushed.

Andrew
diff mbox series

Patch

commit 0d0bbb379d7e5f029d0fb05465fac996493e7850
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Wed Oct 21 19:55:28 2020 -0400

    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.

diff --git a/gcc/testsuite/gcc.dg/pr97515.c b/gcc/testsuite/gcc.dg/pr97515.c
new file mode 100644
index 00000000000..2b6185ec90b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97515.c
@@ -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;
+}
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 5370a23fe18..23ba48d73a7 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -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))
-    return 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))
-    return 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;
 
 }