diff mbox

Fix up noce_try_abs again (PR rtl-optimization/68670)

Message ID 20151209223703.GW5675@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Dec. 9, 2015, 10:37 p.m. UTC
Hi!

Not sure what I've been thinking when writing the previous noce_try_abs fix.
I thought that the optimization can be applied for all the conditions,
and whether it can be applied depends on if it is cond ? ~x : x or
cond ? x : ~x.  But that is not the case, the optimization can be only
applied to a subset of conditions, and when it can be applied, it can be
applied to both the cond ? ~x : x and cond ? x : ~x cases (depending on
the condition one is one_cmpl_abs (x) and the other ~one_cmpl_abs (x)).
So, the previous patch fixed some cases (the ones triggered in the
testcases), kept other cases broken (as can be seen in the new testcases),
pessimized some cases (stopped applying one_cmpl_abs when it could be
applied) and kept optimizing other cases.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk/5.4?

2015-12-09  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/68376
	PR rtl-optimization/68670
	* ifcvt.c (noce_try_abs): For one_cmpl allow < 0, >= 0
	or > -1 conditions regardless of negate, and disallow
	all other conditions.

	* gcc.c-torture/execute/pr68376-2.c (f5, f6, f7, f8): New
	tests.
	(main): Call them.
	* gcc.dg/pr68670-1.c: New test.
	* gcc.dg/pr68670-2.c: New test.


	Jakub

Comments

Bernd Schmidt Dec. 10, 2015, 1:20 p.m. UTC | #1
On 12/09/2015 11:37 PM, Jakub Jelinek wrote:
> Not sure what I've been thinking when writing the previous noce_try_abs fix.
> I thought that the optimization can be applied for all the conditions,
> and whether it can be applied depends on if it is cond ? ~x : x or
> cond ? x : ~x.  But that is not the case, the optimization can be only
> applied to a subset of conditions, and when it can be applied, it can be
> applied to both the cond ? ~x : x and cond ? x : ~x cases (depending on
> the condition one is one_cmpl_abs (x) and the other ~one_cmpl_abs (x)).

Odd, I thought you made a good argument last time :-( Sorry for not 
catching the problem.

>   	switch (GET_CODE (cond))
>   	  {
> -	  case GT:
> -	    if (!negate)
> -	      return FALSE;
> -	    break;
>   	  case GE:
> -	    /* >= 0 is the same case as above > -1.  */
> -	    if (negate)
> -	      return FALSE;
> -	    break;
>   	  case LT:
> -	    if (negate)
> -	      return FALSE;
> -	    break;
> -	  case LE:
> -	    /* <= 0 is the same case as above < 1.  */
> -	    if (!negate)
> -	      return FALSE;
>   	    break;
>   	  default:
>   	    return FALSE;

This turns into a much simpler if statement, doesn't it? Ok with that 
change.

> +/* PR rtl-optimization/68670 */
> +/* { dg-do run } */
> +/* { dg-options "-O2 -ftracer" } */

Curious what effect -ftracer has here?


Bernd
Jakub Jelinek Dec. 10, 2015, 1:26 p.m. UTC | #2
On Thu, Dec 10, 2015 at 02:20:04PM +0100, Bernd Schmidt wrote:
> This turns into a much simpler if statement, doesn't it? Ok with that
> change.

Ok, will do, thanks.

> >+/* PR rtl-optimization/68670 */
> >+/* { dg-do run } */
> >+/* { dg-options "-O2 -ftracer" } */
> 
> Curious what effect -ftracer has here?

In one case it was seeing all test_bb/then_bb/else_bb/join_bb,
where one of then_bb/else_bb (don't remember which one) contained
y = ~x and another one y = x, while the other case had no else_bb,
with already test_bb doing y = x and then_bb then doing y = ~y.
Correspondingly different condition, different negate value.

	Jakub
diff mbox

Patch

--- gcc/ifcvt.c.jj	2015-12-03 16:39:36.000000000 +0100
+++ gcc/ifcvt.c	2015-12-09 17:18:35.418052077 +0100
@@ -2601,17 +2601,14 @@  noce_try_abs (struct noce_if_info *if_in
      Note that these rtx constants are known to be CONST_INT, and
      therefore imply integer comparisons.
      The one_cmpl case is more complicated, as we want to handle
-     only x < 0 ? ~x : x or x >= 0 ? ~x : x but not
-     x <= 0 ? ~x : x or x > 0 ? ~x : x, as the latter two
-     have different result for x == 0.  */
+     only x < 0 ? ~x : x or x >= 0 ? x : ~x to one_cmpl_abs (x)
+     and x < 0 ? x : ~x or x >= 0 ? ~x : x to ~one_cmpl_abs (x),
+     but not other cases (x > -1 is equivalent of x >= 0).  */
   if (c == constm1_rtx && GET_CODE (cond) == GT)
-    {
-      if (one_cmpl && negate)
-	return FALSE;
-    }
+    ;
   else if (c == const1_rtx && GET_CODE (cond) == LT)
     {
-      if (one_cmpl && !negate)
+      if (one_cmpl)
 	return FALSE;
     }
   else if (c == CONST0_RTX (GET_MODE (b)))
@@ -2619,23 +2616,8 @@  noce_try_abs (struct noce_if_info *if_in
       if (one_cmpl)
 	switch (GET_CODE (cond))
 	  {
-	  case GT:
-	    if (!negate)
-	      return FALSE;
-	    break;
 	  case GE:
-	    /* >= 0 is the same case as above > -1.  */
-	    if (negate)
-	      return FALSE;
-	    break;
 	  case LT:
-	    if (negate)
-	      return FALSE;
-	    break;
-	  case LE:
-	    /* <= 0 is the same case as above < 1.  */
-	    if (!negate)
-	      return FALSE;
 	    break;
 	  default:
 	    return FALSE;
--- gcc/testsuite/gcc.c-torture/execute/pr68376-2.c.jj	2015-11-19 09:48:05.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr68376-2.c	2015-12-09 17:58:57.000000000 +0100
@@ -26,6 +26,30 @@  f4 (int x)
   return x <= 0 ? x : ~x;
 }
 
+__attribute__((noinline, noclone)) int
+f5 (int x)
+{
+  return x >= 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f6 (int x)
+{
+  return x >= 0 ? x : ~x;
+}
+
+__attribute__((noinline, noclone)) int
+f7 (int x)
+{
+  return x > 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f8 (int x)
+{
+  return x > 0 ? x : ~x;
+}
+
 int
 main ()
 {
@@ -37,5 +61,13 @@  main ()
     abort ();
   if (f4 (5) != -6 || f4 (-5) != -5 || f4 (0) != 0)
     abort ();
+  if (f5 (5) != -6 || f5 (-5) != -5 || f5 (0) != -1)
+    abort ();
+  if (f6 (5) != 5 || f6 (-5) != 4 || f6 (0) != 0)
+    abort ();
+  if (f7 (5) != -6 || f7 (-5) != -5 || f7 (0) != 0)
+    abort ();
+  if (f8 (5) != 5 || f8 (-5) != 4 || f8 (0) != -1)
+    abort ();
   return 0;
 }
--- gcc/testsuite/gcc.dg/pr68670-1.c.jj	2015-12-09 17:22:41.465621589 +0100
+++ gcc/testsuite/gcc.dg/pr68670-1.c	2015-12-09 17:22:05.251126555 +0100
@@ -0,0 +1,5 @@ 
+/* PR rtl-optimization/68670 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ftracer" } */
+
+#include "../gcc.c-torture/execute/pr68376-1.c"
--- gcc/testsuite/gcc.dg/pr68670-2.c.jj	2015-12-09 17:22:44.528578868 +0100
+++ gcc/testsuite/gcc.dg/pr68670-2.c	2015-12-09 17:22:31.641758606 +0100
@@ -0,0 +1,5 @@ 
+/* PR rtl-optimization/68670 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ftracer" } */
+
+#include "../gcc.c-torture/execute/pr68376-2.c"