Selectively trap if ranger and vr-values disagree on range builtins.
authorAldy Hernandez <aldyh@redhat.com>
Thu, 22 Oct 2020 06:39:04 +0000 (08:39 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Thu, 29 Oct 2020 14:40:39 +0000 (15:40 +0100)
The UBSAN builtins degrade into PLUS/MINUS/MULT and call
extract_range_from_binary_expr, which as the PR shows, can special
case some symbolics which the ranger doesn't currently handle.

Looking at vr_values::extract_range_builtin(), I see that every single
place where we ask for a range, we bail on non-integers (symbolics,
etc).  That is, with the exception of the UBSAN builtins.

Since this seems to be particular to UBSAN, we could still go with the
original plan of removing the duplicity in ranger vs vr-values, but
leave in the UBSAN builtin handling.  This isn't ideal, as we'd like
to remove all the common code, but I'd be willing to put up with UBSAN
duplication for the time being.

This patch disables the assert on the UBSAN builtins, while still
trapping if any other differences are found between the vr_values and
the ranger versions of builtin range handling.

As a follow-up, once Fedora can test this approach, I'll remove all
the builtin code from extract_range_builtin, with the exception of the
UBSAN stuff (renaming it to extract_range_ubsan_builtin).

Since the builtin code has proven fickle across architectures, I've
tested this with {-m32,-m64,-fsanitize=signed-integer-overflow} on
x86, ppc64le, and aarch64.  I think this should be enough.  If it
isn't, we can revert the patch, and leave the duplicate code until
the next release cycle when hopefully vr_values, evrp, and friends
will all be overhauled.

gcc/ChangeLog:

PR tree-optimization/97505
* vr-values.c (vr_values::extract_range_basic): Enable
trap again for everything except UBSAN builtins.

gcc/vr-values.c

index 7a0e70eab64230158f76994aa64f831c0bdec19a..9f5943a1ab6e0e966880b3a8643a4a710a291ab2 100644 (file)
@@ -1432,14 +1432,17 @@ vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt)
 
   if (is_gimple_call (stmt) && extract_range_builtin (vr, stmt))
     {
+      combined_fn cfn = gimple_call_combined_fn (stmt);
+      if (cfn == CFN_UBSAN_CHECK_ADD
+         || cfn == CFN_UBSAN_CHECK_SUB
+         || cfn == CFN_UBSAN_CHECK_MUL)
+       return;
+
       value_range_equiv tmp;
       /* Assert that any ranges vr_values::extract_range_builtin gets
         are also handled by the ranger counterpart.  */
       gcc_assert (range_of_builtin_call (*this, tmp, as_a<gcall *> (stmt)));
-#if 0
-      /* Disable this while PR97505 is resolved.  */
       gcc_assert (tmp.equal_p (*vr, /*ignore_equivs=*/false));
-#endif
       return;
     }
   /* Handle extraction of the two results (result of arithmetics and