* [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).