public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][8/n] Remove GENERIC stmt combining from SCCVN
@ 2015-06-30 10:06 Richard Biener
  2015-07-05 16:05 ` Eric Botcazou
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Biener @ 2015-06-30 10:06 UTC (permalink / raw)
  To: gcc-patches


The following moves some bitwise patterns from the match-and-simplify
branch, extending them with proper conditional converts and removing
the corresponding patterns from fold-const.c

Bootstrap & regtest in progress on x86_64-unknown-linux-gnu.

Richard.

2015-06-30  Richard Biener  <rguenther@suse.de>

	* fold-const.c (fold_binary_loc): Move ~x & ~y -> ~(x | y) and
	~x | ~y -> ~(x & y), (x & CST) ^ (x & CST2) -> (x & CST) | (x & CST2),
	(X | Y) ^ X -> Y & ~ X, ~X ^ ~Y to X ^ Y and ~X ^ C to X ^ ~C ...
	* match.pd: ... to patterns here.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 225164)
+++ gcc/fold-const.c	(working copy)
@@ -10996,24 +10996,6 @@ fold_binary_loc (location_t loc,
       if (t1 != NULL_TREE)
 	return t1;
 
-      /* Convert (or (not arg0) (not arg1)) to (not (and (arg0) (arg1))).
-
-	 This results in more efficient code for machines without a NAND
-	 instruction.  Combine will canonicalize to the first form
-	 which will allow use of NAND instructions provided by the
-	 backend if they exist.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
-	{
-	  return
-	    fold_build1_loc (loc, BIT_NOT_EXPR, type,
-			 build2 (BIT_AND_EXPR, type,
-				 fold_convert_loc (loc, type,
-						   TREE_OPERAND (arg0, 0)),
-				 fold_convert_loc (loc, type,
-						   TREE_OPERAND (arg1, 0))));
-	}
-
       /* See if this can be simplified into a rotate first.  If that
 	 is unsuccessful continue in the association code.  */
       goto bit_rotate;
@@ -11037,90 +11019,6 @@ fold_binary_loc (location_t loc,
 	  return omit_one_operand_loc (loc, type, t1, arg0);
 	}
 
-      /* If we are XORing two BIT_AND_EXPR's, both of which are and'ing
-         with a constant, and the two constants have no bits in common,
-	 we should treat this as a BIT_IOR_EXPR since this may produce more
-	 simplifications.  */
-      if (TREE_CODE (arg0) == BIT_AND_EXPR
-	  && TREE_CODE (arg1) == BIT_AND_EXPR
-	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
-	  && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
-	  && wi::bit_and (TREE_OPERAND (arg0, 1),
-			  TREE_OPERAND (arg1, 1)) == 0)
-	{
-	  code = BIT_IOR_EXPR;
-	  goto bit_ior;
-	}
-
-      /* (X | Y) ^ X -> Y & ~ X*/
-      if (TREE_CODE (arg0) == BIT_IOR_EXPR
-          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
-        {
-	  tree t2 = TREE_OPERAND (arg0, 1);
-	  t1 = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1),
-			    arg1);
-	  t1 = fold_build2_loc (loc, BIT_AND_EXPR, type,
-			    fold_convert_loc (loc, type, t2),
-			    fold_convert_loc (loc, type, t1));
-	  return t1;
-	}
-
-      /* (Y | X) ^ X -> Y & ~ X*/
-      if (TREE_CODE (arg0) == BIT_IOR_EXPR
-          && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
-        {
-	  tree t2 = TREE_OPERAND (arg0, 0);
-	  t1 = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1),
-			    arg1);
-	  t1 = fold_build2_loc (loc, BIT_AND_EXPR, type,
-			    fold_convert_loc (loc, type, t2),
-			    fold_convert_loc (loc, type, t1));
-	  return t1;
-	}
-
-      /* X ^ (X | Y) -> Y & ~ X*/
-      if (TREE_CODE (arg1) == BIT_IOR_EXPR
-          && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
-        {
-	  tree t2 = TREE_OPERAND (arg1, 1);
-	  t1 = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg0),
-			    arg0);
-	  t1 = fold_build2_loc (loc, BIT_AND_EXPR, type,
-			    fold_convert_loc (loc, type, t2),
-			    fold_convert_loc (loc, type, t1));
-	  return t1;
-	}
-
-      /* X ^ (Y | X) -> Y & ~ X*/
-      if (TREE_CODE (arg1) == BIT_IOR_EXPR
-          && operand_equal_p (TREE_OPERAND (arg1, 1), arg0, 0))
-        {
-	  tree t2 = TREE_OPERAND (arg1, 0);
-	  t1 = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg0),
-			    arg0);
-	  t1 = fold_build2_loc (loc, BIT_AND_EXPR, type,
-			    fold_convert_loc (loc, type, t2),
-			    fold_convert_loc (loc, type, t1));
-	  return t1;
-	}
-
-      /* Convert ~X ^ ~Y to X ^ Y.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
-	return fold_build2_loc (loc, code, type,
-			    fold_convert_loc (loc, type,
-					      TREE_OPERAND (arg0, 0)),
-			    fold_convert_loc (loc, type,
-					      TREE_OPERAND (arg1, 0)));
-
-      /* Convert ~X ^ C to X ^ ~C.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-	  && TREE_CODE (arg1) == INTEGER_CST)
-	return fold_build2_loc (loc, code, type,
-			    fold_convert_loc (loc, type,
-					      TREE_OPERAND (arg0, 0)),
-			    fold_build1_loc (loc, BIT_NOT_EXPR, type, arg1));
-
       /* Fold (X & 1) ^ 1 as (X & 1) == 0.  */
       if (TREE_CODE (arg0) == BIT_AND_EXPR
 	  && INTEGRAL_TYPE_P (type)
@@ -11432,23 +11330,6 @@ fold_binary_loc (location_t loc,
 	      fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
 	}
 
-      /* Convert (and (not arg0) (not arg1)) to (not (or (arg0) (arg1))).
-
-	 This results in more efficient code for machines without a NOR
-	 instruction.  Combine will canonicalize to the first form
-	 which will allow use of NOR instructions provided by the
-	 backend if they exist.  */
-      if (TREE_CODE (arg0) == BIT_NOT_EXPR
-	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
-	{
-	  return fold_build1_loc (loc, BIT_NOT_EXPR, type,
-			      build2 (BIT_IOR_EXPR, type,
-				      fold_convert_loc (loc, type,
-							TREE_OPERAND (arg0, 0)),
-				      fold_convert_loc (loc, type,
-							TREE_OPERAND (arg1, 0))));
-	}
-
       /* If arg0 is derived from the address of an object or function, we may
 	 be able to fold this expression using the object or function's
 	 alignment.  */
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 225164)
+++ gcc/match.pd	(working copy)
@@ -389,6 +389,47 @@ (define_operator_list swapped_tcc_compar
  (bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 (bit_not @0)))
  (bit_and @0 @1))
 
+/* ~x & ~y -> ~(x | y)
+   ~x | ~y -> ~(x & y) */
+(for op (bit_and bit_ior)
+     rop (bit_ior bit_and)
+ (simplify
+  (op (convert1? (bit_not @0)) (convert2? (bit_not @1)))
+  (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
+       && tree_nop_conversion_p (type, TREE_TYPE (@1)))
+   (bit_not (rop (convert @0) (convert @1))))))
+
+/* If we are XORing two BIT_AND_EXPR's, both of which are and'ing
+   with a constant, and the two constants have no bits in common,
+   we should treat this as a BIT_IOR_EXPR since this may produce more
+   simplifications.  */
+(simplify
+ (bit_xor (convert1? (bit_and@4 @0 INTEGER_CST@1))
+          (convert2? (bit_and@5 @2 INTEGER_CST@3)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
+      && tree_nop_conversion_p (type, TREE_TYPE (@2))
+      && wi::bit_and (@1, @3) == 0)
+  (bit_ior (convert @4) (convert @5))))
+
+/* (X | Y) ^ X -> Y & ~ X*/
+(simplify
+ (bit_xor:c (convert? (bit_ior:c @0 @1)) (convert? @0))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+  (convert (bit_and @1 (bit_not @0)))))
+
+/* Convert ~X ^ ~Y to X ^ Y.  */
+(simplify
+ (bit_xor (convert1? (bit_not @0)) (convert2? (bit_not @1)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
+      && tree_nop_conversion_p (type, TREE_TYPE (@1)))
+  (bit_xor (convert @0) (convert @1))))
+
+/* Convert ~X ^ C to X ^ ~C.  */
+(simplify
+ (bit_xor (convert? (bit_not @0)) INTEGER_CST@1)
+ (bit_xor (convert @0) (bit_not @1)))
+
+
 (simplify
  (abs (negate @0))
  (abs @0))

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][8/n] Remove GENERIC stmt combining from SCCVN
  2015-06-30 10:06 [PATCH][8/n] Remove GENERIC stmt combining from SCCVN Richard Biener
@ 2015-07-05 16:05 ` Eric Botcazou
  2015-07-06  6:31   ` Richard Biener
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Botcazou @ 2015-07-05 16:05 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 808 bytes --]

> The following moves some bitwise patterns from the match-and-simplify
> branch, extending them with proper conditional converts and removing
> the corresponding patterns from fold-const.c

There is a pasto/thinko in the last pattern:

/* Convert ~X ^ C to X ^ ~C.  */
(simplify
 (bit_xor (convert? (bit_not @0)) INTEGER_CST@1)
 (bit_xor (convert @0) (bit_not @1)))

That's incorrect if the types don't have the same precision, as in the other 
cases, and is responsible for PR tree-optimization/66757.

Tested on x86_64-suse-linux, OK for the mainline?


2015-07-05 Eric Botcazou  <ebotcazou@adacore.com>

	PR tree-optimization/66757
	* match.pd: Add missing condition to ~X ^ C -> X ^ ~C.

2015-07-05 Eric Botcazou  <ebotcazou@adacore.com>

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

-- 
Eric Botcazou

[-- Attachment #2: pr66757.diff --]
[-- Type: text/x-patch, Size: 481 bytes --]

Index: match.pd
===================================================================
--- match.pd	(revision 225410)
+++ match.pd	(working copy)
@@ -444,7 +444,8 @@ (define_operator_list CBRT BUILT_IN_CBRT
 /* Convert ~X ^ C to X ^ ~C.  */
 (simplify
  (bit_xor (convert? (bit_not @0)) INTEGER_CST@1)
- (bit_xor (convert @0) (bit_not @1)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+  (bit_xor (convert @0) (bit_not @1))))
 
 /* Fold (X & Y) ^ Y as ~X & Y.  */
 (simplify

[-- Attachment #3: pr66757.c --]
[-- Type: text/x-csrc, Size: 217 bytes --]

/* PR tree-optimization/66757 */
/* Testcase by Zhendong Su <su@cs.ucdavis.edu> */

int a, b;

int
main (void)
{
  unsigned int t = (unsigned char) (~b); 

  if ((t ^ 1) / 255)
    __builtin_abort (); 

  return 0;
}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][8/n] Remove GENERIC stmt combining from SCCVN
  2015-07-05 16:05 ` Eric Botcazou
@ 2015-07-06  6:31   ` Richard Biener
  2015-07-06  8:36     ` Eric Botcazou
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Biener @ 2015-07-06  6:31 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Sun, 5 Jul 2015, Eric Botcazou wrote:

> > The following moves some bitwise patterns from the match-and-simplify
> > branch, extending them with proper conditional converts and removing
> > the corresponding patterns from fold-const.c
> 
> There is a pasto/thinko in the last pattern:
> 
> /* Convert ~X ^ C to X ^ ~C.  */
> (simplify
>  (bit_xor (convert? (bit_not @0)) INTEGER_CST@1)
>  (bit_xor (convert @0) (bit_not @1)))
> 
> That's incorrect if the types don't have the same precision, as in the other 
> cases, and is responsible for PR tree-optimization/66757.

Hum, somehow I convinced myself that it was ok if the precision
wasn't the same (but I can't remember my line of thought).  Your
testcase clearly shows I was wrong ;)

> Tested on x86_64-suse-linux, OK for the mainline?

Ok.

Thanks,
Richard.

> 
> 2015-07-05 Eric Botcazou  <ebotcazou@adacore.com>
> 
> 	PR tree-optimization/66757
> 	* match.pd: Add missing condition to ~X ^ C -> X ^ ~C.
> 
> 2015-07-05 Eric Botcazou  <ebotcazou@adacore.com>
> 
> 	* gcc.c-torture/execute/pr66757.c: New test.
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][8/n] Remove GENERIC stmt combining from SCCVN
  2015-07-06  6:31   ` Richard Biener
@ 2015-07-06  8:36     ` Eric Botcazou
  0 siblings, 0 replies; 4+ messages in thread
From: Eric Botcazou @ 2015-07-06  8:36 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

> Hum, somehow I convinced myself that it was ok if the precision
> wasn't the same (but I can't remember my line of thought).  Your
> testcase clearly shows I was wrong ;)

It's not mine, but Zhendong Su's.  For the sake of completeness, I also had an 
Ada testcase, but I know how convincing C testcases can be. :-)

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-07-06  8:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-30 10:06 [PATCH][8/n] Remove GENERIC stmt combining from SCCVN Richard Biener
2015-07-05 16:05 ` Eric Botcazou
2015-07-06  6:31   ` Richard Biener
2015-07-06  8:36     ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).