On Mon, Feb 25, 2019 at 10:07:10AM +0100, Eric Botcazou wrote:
> 2019-02-25  Eric Botcazou  <ebotca...@adacore.com>
> 
>       * tree-ssa-dom.c (edge_info::derive_equivalences) <BIT_IOR_EXPR>: Fix
>       and move around comment.
>       <BIT_AND_EXPR>: Likewise.
>       <BIT_NOT_EXPR>: Add specific handling for boolean types.

This broke the following testcase, as mentioned in the PR we have
expected value of the BIT_NOT_EXPR -2 and because that is not zero, the
code assumed that it must be zero, when it actually must be ~-2, i.e. 1.

I know Eric has committed a tweak here, but I view this magic handling as
something meant for boolean types only (if it is correct at all and the
right fix wouldn't be avoid the BIT_NOT_EXPR for the prec > 1 booleans, I
believe the expansion of BIT_NOT_EXPR doesn't have any special case for
BOOLEAN_TYPE).  This patch just restores previous behavior for non-boolean
types (basically inlines the first two cases from ssa_name_has_boolean_range
while leaving the problematic third one out, normal integral types with just
known value range of [0,1]).

2019-02-28  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/89536
        * tree-ssa-dom.c (edge_info::derive_equivalences) <case BIT_NOT_EXPR>:
        Don't use ssa_name_has_boolean_range here, check only for boolean type
        or unsigned integral type with precision 1.

        * gcc.c-torture/execute/pr89536.c: New test.

--- gcc/tree-ssa-dom.c.jj       2019-02-26 14:13:08.296824100 +0100
+++ gcc/tree-ssa-dom.c  2019-02-28 15:52:08.737369799 +0100
@@ -346,7 +346,14 @@ edge_info::derive_equivalences (tree nam
               boolean types with precision > 1.  */
            if (code == BIT_NOT_EXPR
                && TREE_CODE (rhs) == SSA_NAME
-               && ssa_name_has_boolean_range (rhs))
+               /* Don't call ssa_name_has_boolean_range here, that returns
+                  true for the following condition, but also when VRP
+                  determines [0, 1] range on anything else.  BIT_NOT_EXPR
+                  of such numbers is [-2, -1] or [-2U, -1U] though.  */
+               && (TREE_CODE (TREE_TYPE (rhs)) == BOOLEAN_TYPE
+                   || (INTEGRAL_TYPE_P (TREE_TYPE (rhs))
+                       && TYPE_UNSIGNED (TREE_TYPE (rhs))
+                       && TYPE_PRECISION (TREE_TYPE (rhs)) == 1)))
              {
                if (integer_zerop (value))
                  res = build_one_cst (TREE_TYPE (rhs));
--- gcc/testsuite/gcc.c-torture/execute/pr89536.c.jj    2019-02-28 
15:53:37.792924793 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr89536.c       2019-02-28 
15:53:08.357402412 +0100
@@ -0,0 +1,14 @@
+/* PR tree-optimization/89536 */
+
+int a = 1;
+
+int
+main ()
+{
+  a = ~(a && 1); 
+  if (a < -1)
+    a = ~a;
+  if (!a)
+    __builtin_abort ();
+  return 0;
+}


        Jakub

Reply via email to