The following fixes PR71762 via reverting the transforms of
~X & Y to X < Y and similar because when the bools they apply to
are expanded to RTL undefined values are not reliably zero-extended
and thus the transform is invalid.  Ensuring the zero-extension
is too costly IMHO and the proper fix is to move the transform
to RTL where we can check known-zero-bits to validate validity
or to fix GIMPLE not not have operations on types not matching their mode
in precision.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk
and branches?

Any takers for the RTL implementation?

Thanks,
Richard.

2016-11-10  Richard Biener  <rguent...@suse.de>

        PR middle-end/71762
        * match.pd ((~X & Y) -> X < Y, (X & ~Y) -> Y < X,
        (~X | Y) -> X <= Y, (X | ~Y) -> Y <= X): Remove.

        * gcc.dg/torture/pr71762-1.c: New testcase.
        * gcc.dg/torture/pr71762-2.c: Likewise.
        * gcc.dg/torture/pr71762-3.c: Likewise.
        * gcc.dg/tree-ssa/forwprop-28.c: XFAIL.

Index: gcc/match.pd
===================================================================
--- gcc/match.pd        (revision 242004)
+++ gcc/match.pd        (working copy)
@@ -944,33 +944,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (op:c truth_valued_p@0 (logical_inverted_value @0))
   { constant_boolean_node (op == NE_EXPR ? true : false, type); }))
 
-/* If arg1 and arg2 are booleans (or any single bit type)
-   then try to simplify:
-
-   (~X & Y) -> X < Y
-   (X & ~Y) -> Y < X
-   (~X | Y) -> X <= Y
-   (X | ~Y) -> Y <= X
-
-   But only do this if our result feeds into a comparison as
-   this transformation is not always a win, particularly on
-   targets with and-not instructions.
-   -> simplify_bitwise_binary_boolean */
-(simplify
-  (ne (bit_and:c (bit_not @0) @1) integer_zerop)
-  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
-       && TYPE_PRECISION (TREE_TYPE (@1)) == 1)
-   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
-    (lt @0 @1)
-    (gt @0 @1))))
-(simplify
-  (ne (bit_ior:c (bit_not @0) @1) integer_zerop)
-  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
-       && TYPE_PRECISION (TREE_TYPE (@1)) == 1)
-   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
-    (le @0 @1)
-    (ge @0 @1))))
-
 /* ~~x -> x */
 (simplify
   (bit_not (bit_not @0))
Index: gcc/testsuite/gcc.dg/torture/pr71762-1.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr71762-1.c    (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr71762-1.c    (working copy)
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fdisable-rtl-init-regs" } */
+
+static _Bool
+foo (_Bool a, _Bool b)
+{
+  int x = a && ! b;
+  return x != 0;
+}
+
+int y = 1;
+int main()
+{
+  _Bool x;
+  if (foo (x, y))
+    __builtin_abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/torture/pr71762-2.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr71762-2.c    (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr71762-2.c    (working copy)
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+
+static _Bool
+foo (_Bool a, _Bool b)
+{
+  int x = a && ! b;
+  return x != 0;
+}
+
+int y = 1;
+int main()
+{
+  _Bool x[32];
+  if (foo (x[1], y))
+    __builtin_abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/torture/pr71762-3.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr71762-3.c    (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr71762-3.c    (working copy)
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+static _Bool
+foo (_Bool a, _Bool b)
+{
+  int x = a && ! b;
+  return x != 0;
+}
+
+int y = 1;
+int main()
+{
+  register _Bool x
+  /* Add register spec for the argv parameter to main.  */
+#if __i386__ || __x86_64__
+      __asm__("%esi")
+#endif
+    ;
+  if (foo (x, y))
+    __builtin_abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c (revision 242032)
+++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c (working copy)
@@ -83,6 +83,8 @@ test_8 (int code)
    to a ordered compare.  But the transform does not trigger if we transform
    the negated code == 22 compare to code != 22 first.  It turns out if
    we do that we even generate better code on x86 at least.  */
+/* ???  As PR71762 notices this transform causes wrong-code issues in RTL
+   with one uninitialized operand, thus it has been disabled.  */
 
-/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* \[<>\]" 4 
"forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* \[<>\]" 4 
"forwprop1" { xfail *-*-* } } } */
 

Reply via email to