Enhance initial global value setting.
authorAndrew MacLeod <amacleod@redhat.com>
Mon, 26 Apr 2021 21:41:22 +0000 (17:41 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Fri, 7 May 2021 18:53:44 +0000 (14:53 -0400)
Incorporate code from vr_values to get safe initial parameter values.
If this is a local automatic which is used before defined, use UNDEFINED.

* gimple-range.h (gimple_range_global): Pick up parameter initial
values, and use-before defined locals are UNDEFINED.

gcc/gimple-range.h

index 5751b09..f331561 100644 (file)
@@ -138,22 +138,39 @@ gimple_range_global (tree name)
 {
   gcc_checking_assert (gimple_range_ssa_p (name));
   tree type = TREE_TYPE (name);
-#if 0
-  // Reenable picking up global ranges when we are OK failing tests that look
-  // for builtin_unreachable in the code, like
-  // RUNTESTFLAGS=dg.exp=pr61034.C check-g++
-  // pre-optimizations (inlining) set a global range which causes the ranger
-  // to remove the condition which leads to builtin_unreachable.
-  if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
+
+  if (SSA_NAME_IS_DEFAULT_DEF (name))
     {
-      // Return a range from an SSA_NAME's available range.
-      wide_int min, max;
-      enum value_range_kind kind = get_range_info (name, &min, &max);
-      return value_range (type, min, max, kind);
-    }
-#endif
- // Otherwise return range for the type.
- return value_range (type);
+      tree sym = SSA_NAME_VAR (name);
+      // Adapted from vr_values::get_lattice_entry().
+      // Use a range from an SSA_NAME's available range.
+      if (TREE_CODE (sym) == PARM_DECL)
+       {
+         // Try to use the "nonnull" attribute to create ~[0, 0]
+         // anti-ranges for pointers.  Note that this is only valid with
+         // default definitions of PARM_DECLs.
+         if (POINTER_TYPE_P (type)
+             && (nonnull_arg_p (sym) || get_ptr_nonnull (name)))
+           {
+             value_range r;
+             r.set_nonzero (type);
+             return r;
+           }
+         else if (INTEGRAL_TYPE_P (type))
+           {
+             value_range r;
+             get_range_info (name, r);
+             if (r.undefined_p ())
+               r.set_varying (type);
+             return r;
+           }
+       }
+      // If this is a local automatic with no definition, use undefined.
+      else if (TREE_CODE (sym) != RESULT_DECL)
+       return value_range ();
+   }
+  // Otherwise return range for the type.
+  return value_range (type);
 }