Re: [PATCH] Fix PR71762

2016-11-23 Thread Richard Biener
On November 23, 2016 6:25:43 PM GMT+01:00, Bernd Schmidt  
wrote:
>On 11/10/2016 02:28 PM, Richard Biener wrote:
>> Any takers for the RTL implementation?
>
>Do you have a testcase you think can be optimized?

The forwrop test case I XFAILed with the patch.

Richard.

>
>Bernd




Re: [PATCH] Fix PR71762

2016-11-23 Thread Bernd Schmidt

On 11/10/2016 02:28 PM, Richard Biener wrote:

Any takers for the RTL implementation?


Do you have a testcase you think can be optimized?


Bernd



Re: [PATCH] Fix PR71762

2016-11-23 Thread Richard Biener
On Thu, 10 Nov 2016, Richard Biener wrote:

> On November 10, 2016 7:39:57 PM GMT+01:00, Marc Glisse  
> wrote:
> >On Thu, 10 Nov 2016, Richard Biener wrote:
> >
> >> 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.
> >
> >Can you explain why this particular transformation is special? We have
> >a 
> >number of other optimizations that take advantage of the fact that bool
> >is 
> >in [0, 1], even without looking at VRP, say for instance x != 0 -> x.
> >Are 
> >we supposed to remove all of them?
> 
> No.  But UNDEFINED & 0 is well-defined
> Even if precision ends up being bigger.  Undefined != 0 is never well-defined.

Now applied to trunk.

Richard.


Re: [PATCH] Fix PR71762

2016-11-10 Thread Richard Biener
On November 10, 2016 7:39:57 PM GMT+01:00, Marc Glisse  
wrote:
>On Thu, 10 Nov 2016, Richard Biener wrote:
>
>> 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.
>
>Can you explain why this particular transformation is special? We have
>a 
>number of other optimizations that take advantage of the fact that bool
>is 
>in [0, 1], even without looking at VRP, say for instance x != 0 -> x.
>Are 
>we supposed to remove all of them?

No.  But UNDEFINED & 0 is well-defined
Even if precision ends up being bigger.  Undefined != 0 is never well-defined.

Richard.




Re: [PATCH] Fix PR71762

2016-11-10 Thread Marc Glisse

On Thu, 10 Nov 2016, Richard Biener wrote:


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.


Can you explain why this particular transformation is special? We have a 
number of other optimizations that take advantage of the fact that bool is 
in [0, 1], even without looking at VRP, say for instance x != 0 -> x. Are 
we supposed to remove all of them?


--
Marc Glisse


[PATCH] Fix PR71762

2016-11-10 Thread Richard Biener

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  

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 *-*-* } } } */