]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
check undefine_p for one more vr
authorJiufu Guo <guojiufu@linux.ibm.com>
Wed, 20 Sep 2023 03:11:58 +0000 (11:11 +0800)
committerguojiufu <guojiufu@linux.ibm.com>
Thu, 21 Sep 2023 05:18:22 +0000 (13:18 +0800)
The root cause of PR111355 and PR111482 is missing to check if vr0
is undefined_p before call vr0.lower_bound.

In the pattern "(X + C) / N",

    (if (INTEGRAL_TYPE_P (type)
 && get_range_query (cfun)->range_of_expr (vr0, @0))
     (if (...)
       (plus (op @0 @2) { wide_int_to_tree (type, plus_op1 (c)); })
       (if (TYPE_UNSIGNED (type) && c.sign_mask () < 0 ...
    && wi::geu_p (vr0.lower_bound (), -c))

In "(if (...)", there is code to prevent vr0's undefined_p,
But in the "else" part, vr0's undefined_p is not checked before
"wi::geu_p (vr0.lower_bound (), -c)".

PR tree-optimization/111355

gcc/ChangeLog:

* match.pd ((X + C) / N): Update pattern.

gcc/testsuite/ChangeLog:

* gcc.dg/pr111355.c: New test.

gcc/match.pd
gcc/testsuite/gcc.dg/pr111355.c [new file with mode: 0644]

index ce24957926f4b4a1dbdb7b5ecc891fb4619705b2..0aa815f4118da492127c65f6aec95034fa4478fd 100644 (file)
@@ -1009,7 +1009,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
              || (vr0.nonnegative_p () && vr3.nonnegative_p ())
              || (vr0.nonpositive_p () && vr3.nonpositive_p ())))
        (plus (op @0 @2) { wide_int_to_tree (type, plus_op1 (c)); })
-       (if (TYPE_UNSIGNED (type) && c.sign_mask () < 0
+       (if (!vr0.undefined_p () && TYPE_UNSIGNED (type) && c.sign_mask () < 0
            && exact_mod (-c)
            /* unsigned "X-(-C)" doesn't underflow.  */
            && wi::geu_p (vr0.lower_bound (), -c))
diff --git a/gcc/testsuite/gcc.dg/pr111355.c b/gcc/testsuite/gcc.dg/pr111355.c
new file mode 100644 (file)
index 0000000..7b522d9
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -Wno-div-by-zero" } */
+
+/* Make sure no ICE. */
+int main() {
+  unsigned b;
+  return b ? 1 << --b / 0 : 0;
+}