]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Use known global ranges in export_global_ranges
authorAldy Hernandez <aldyh@redhat.com>
Tue, 1 Jun 2021 15:48:30 +0000 (17:48 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Thu, 3 Jun 2021 14:39:33 +0000 (16:39 +0200)
This patch modifies export_global_ranges to take into account current
global ranges.  It also handles enhances said function to export pointer
global ranges as well.

gcc/ChangeLog:

* gimple-range.cc (gimple_ranger::export_global_ranges): Call
  update_global_range.
* value-query.cc (update_global_range): New.
* value-query.h (update_global_range): New.

gcc/testsuite/ChangeLog:

* gcc.dg/pr80776-1.c: XFAIL and document the reason why.

gcc/gimple-range.cc
gcc/testsuite/gcc.dg/pr80776-1.c
gcc/value-query.cc
gcc/value-query.h

index ed0a0c9702b7929348a94fa260d9035df5041469..af4262070926219729c94decf727927fa17fd519 100644 (file)
@@ -1115,7 +1115,7 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
 }
 
 // This routine will export whatever global ranges are known to GCC
-// SSA_RANGE_NAME_INFO fields.
+// SSA_RANGE_NAME_INFO and SSA_NAME_PTR_INFO fields.
 
 void
 gimple_ranger::export_global_ranges ()
@@ -1136,24 +1136,18 @@ gimple_ranger::export_global_ranges ()
          && m_cache.get_global_range (r, name)
          && !r.varying_p())
        {
-         // Make sure the new range is a subset of the old range.
-         int_range_max old_range;
-         old_range = gimple_range_global (name);
-         old_range.intersect (r);
-         /* Disable this while we fix tree-ssa/pr61743-2.c.  */
-         //gcc_checking_assert (old_range == r);
-
-         // WTF? Can't write non-null pointer ranges?? stupid set_range_info!
-         if (!POINTER_TYPE_P (TREE_TYPE (name)) && !r.undefined_p ())
+         bool updated = update_global_range (r, name);
+
+         if (updated && dump_file)
            {
              value_range vr = r;
-             set_range_info (name, vr);
-             if (dump_file)
+             print_generic_expr (dump_file, name , TDF_SLIM);
+             fprintf (dump_file, " --> ");
+             vr.dump (dump_file);
+             fprintf (dump_file, "\n");
+             int_range_max same = vr;
+             if (same != r)
                {
-                 print_generic_expr (dump_file, name , TDF_SLIM);
-                 fprintf (dump_file, " --> ");
-                 vr.dump (dump_file);
-                 fprintf (dump_file, "\n");
                  fprintf (dump_file, "         irange : ");
                  r.dump (dump_file);
                  fprintf (dump_file, "\n");
index f3a120b67443a9e2cd3ebba5972736928bbeef5f..eca5e805ae2805d6afb791755bb755b770059112 100644 (file)
@@ -17,5 +17,15 @@ Foo (void)
     __builtin_unreachable ();
   if (! (0 <= i && i <= 999999))
     __builtin_unreachable ();
-  sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */
+
+  /* Legacy evrp sets the range of i to [0, MAX] *before* the first conditional,
+     and to [0,999999] *before* the second conditional.  This is because both
+     evrp and VRP use trickery to set global ranges when this particular use of
+     a __builtin_unreachable is in play (see uses of
+     assert_unreachable_fallthru_edge_p).
+
+     Setting these ranges at the definition site, causes VRP to remove the
+     unreachable code altogether, leaving the following sprintf unguarded.  This
+     causes the bogus warning below.  */
+  sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */
 }
index f8b457d362c79f07128cfee588874c44059e3e5c..070d706166ee12d60d8ac32ee5411edbaa9f29e9 100644 (file)
@@ -224,6 +224,45 @@ get_ssa_name_ptr_info_nonnull (const_tree name)
   return !pi->pt.null;
 }
 
+// Update the global range for NAME into the SSA_RANGE_NAME_INFO and
+// SSA_NAME_PTR_INFO fields.  Return TRUE if the range for NAME was
+// updated.
+
+bool
+update_global_range (irange &r, tree name)
+{
+  tree type = TREE_TYPE (name);
+
+  if (r.undefined_p () || r.varying_p ())
+    return false;
+
+  if (INTEGRAL_TYPE_P (type))
+    {
+      // If a global range already exists, incorporate it.
+      if (SSA_NAME_RANGE_INFO (name))
+       {
+         value_range glob;
+         get_ssa_name_range_info (glob, name);
+         r.intersect (glob);
+       }
+      if (r.undefined_p ())
+       return false;
+
+      value_range vr = r;
+      set_range_info (name, vr);
+      return true;
+    }
+  else if (POINTER_TYPE_P (type))
+    {
+      if (r.nonzero_p ())
+       {
+         set_ptr_nonnull (name);
+         return true;
+       }
+    }
+  return false;
+}
+
 // Return the legacy global range for NAME if it has one, otherwise
 // return VARYING.
 
index 97da663774746b8cb5523d41b45961fc89ed6cf8..d0512e40c5a54773fd7d5d91891e36256c6ca9ef 100644 (file)
@@ -115,5 +115,6 @@ public:
 
 extern global_range_query global_ranges;
 extern value_range gimple_range_global (tree name);
+extern bool update_global_range (irange &r, tree name);
 
 #endif // GCC_QUERY_H