Check for undefined before not returning a constant value
authorAndrew MacLeod <amacleod@redhat.com>
Wed, 21 Oct 2020 23:55:28 +0000 (19:55 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Thu, 22 Oct 2020 00:02:22 +0000 (20:02 -0400)
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.

gcc/testsuite/gcc.dg/pr97515.c [new file with mode: 0644]
gcc/value-query.cc

diff --git a/gcc/testsuite/gcc.dg/pr97515.c b/gcc/testsuite/gcc.dg/pr97515.c
new file mode 100644 (file)
index 0000000..2b6185e
--- /dev/null
@@ -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;
+}
index 5370a23fe18c2d90233ad899b14337b2f9963853..23ba48d73a7710415eb3496f19c0c24a4aefeca2 100644 (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))
-    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;
 
 }