From 03cc70b5f1999fe04354c0ba2227fce733308ad4 Mon Sep 17 00:00:00 2001 From: MCC CS Date: Mon, 1 Oct 2018 11:25:45 +0000 Subject: [PATCH] re PR tree-optimization/87261 (Optimize bool expressions) 2018-10-01 MCC CS PR tree-optimization/87261 * match.pd: Remove trailing whitespace. Add (x & y) | ~(x | y) -> ~(x ^ y), (~x | y) ^ (x ^ y) -> x | ~y and (x ^ y) | ~(x | y) -> ~(x & y) * gcc.dg/pr87261.c: New test. From-SVN: r264744 --- gcc/ChangeLog | 7 ++++++ gcc/match.pd | 49 +++++++++++++++++++++++++++++++----------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr87261.c | 35 ++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr87261.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5214064..70bfeb6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-10-01 MCC CS + + PR tree-optimization/87261 + * match.pd: Remove trailing whitespace. + Add (x & y) | ~(x | y) -> ~(x ^ y), + (~x | y) ^ (x ^ y) -> x | ~y and (x ^ y) | ~(x | y) -> ~(x & y) + 2018-10-01 Claudiu Zissulescu * config/arc/arc.md (*add_n): Clean up pattern, update instruction diff --git a/gcc/match.pd b/gcc/match.pd index ae26ec2..db0e4a8 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -92,7 +92,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) IFN_FMA IFN_FMS IFN_FNMA IFN_FNMS) (define_operator_list COND_TERNARY IFN_COND_FMA IFN_COND_FMS IFN_COND_FNMA IFN_COND_FNMS) - + /* As opposed to convert?, this still creates a single pattern, so it is not a suitable replacement for convert? in all cases. */ (match (nop_convert @0) @@ -106,7 +106,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && tree_nop_conversion_p (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0)))))) /* This one has to be last, or it shadows the others. */ (match (nop_convert @0) - @0) + @0) /* Transform likes of (char) ABS_EXPR <(int) x> into (char) ABSU_EXPR ABSU_EXPR returns unsigned absolute value of the operand and the operand @@ -285,7 +285,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) And not for _Fract types where we can't build 1. */ (if (!integer_zerop (@0) && !ALL_FRACT_MODE_P (TYPE_MODE (type))) { build_one_cst (type); })) - /* X / abs (X) is X < 0 ? -1 : 1. */ + /* X / abs (X) is X < 0 ? -1 : 1. */ (simplify (div:C @0 (abs @0)) (if (INTEGRAL_TYPE_P (type) @@ -929,6 +929,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bitop:c @0 (bit_not (bitop:cs @0 @1))) (bitop @0 (bit_not @1)))) +/* (~x & y) | ~(x | y) -> ~x */ +(simplify + (bit_ior:c (bit_and:c (bit_not@2 @0) @1) (bit_not (bit_ior:c @0 @1))) + @2) + +/* (x | y) ^ (x | ~y) -> ~x */ +(simplify + (bit_xor:c (bit_ior:c @0 @1) (bit_ior:c @0 (bit_not @1))) + (bit_not @0)) + +/* (x & y) | ~(x | y) -> ~(x ^ y) */ +(simplify + (bit_ior:c (bit_and:s @0 @1) (bit_not:s (bit_ior:s @0 @1))) + (bit_not (bit_xor @0 @1))) + +/* (~x | y) ^ (x ^ y) -> x | ~y */ +(simplify + (bit_xor:c (bit_ior:cs (bit_not @0) @1) (bit_xor:s @0 @1)) + (bit_ior @0 (bit_not @1))) + +/* (x ^ y) | ~(x | y) -> ~(x & y) */ +(simplify + (bit_ior:c (bit_xor:s @0 @1) (bit_not:s (bit_ior:s @0 @1))) + (bit_not (bit_and @0 @1))) + /* (x | y) & ~x -> y & ~x */ /* (x & y) | ~x -> y | ~x */ (for bitop (bit_and bit_ior) @@ -1139,7 +1164,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) && tree_nop_conversion_p (type, TREE_TYPE (@1))) (mult (convert @0) (convert (negate @1))))) - + /* -(A + B) -> (-B) - A. */ (simplify (negate (plus:c @0 negate_expr_p@1)) @@ -3099,7 +3124,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (tree_int_cst_sgn (@1) < 0) (scmp @0 @2) (cmp @0 @2)))))) - + /* Simplify comparison of something with itself. For IEEE floating-point, we can only do some of these simplifications. */ (for cmp (eq ge le) @@ -3170,11 +3195,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) } tree newtype = (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type1) - ? TREE_TYPE (@0) : type1); + ? TREE_TYPE (@0) : type1); } (if (TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (newtype)) (cmp (convert:newtype @0) (convert:newtype @1)))))) - + (simplify (cmp @0 REAL_CST@1) /* IEEE doesn't distinguish +0 and -0 in comparisons. */ @@ -3422,7 +3447,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (FTYPE) N == CST -> 0 (FTYPE) N != CST -> 1. */ (if (cmp == EQ_EXPR || cmp == NE_EXPR) - { constant_boolean_node (cmp == NE_EXPR, type); }) + { constant_boolean_node (cmp == NE_EXPR, type); }) /* Otherwise replace with sensible integer constant. */ (with { @@ -3666,7 +3691,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (cmp (bit_and@2 @0 integer_pow2p@1) @1) (icmp @2 { build_zero_cst (TREE_TYPE (@0)); }))) - + /* If we have (A & C) != 0 ? D : 0 where C and D are powers of 2, convert this into a shift followed by ANDing with D. */ (simplify @@ -3886,7 +3911,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (cmp == LE_EXPR) (ge (convert:st @0) { build_zero_cst (st); }) (lt (convert:st @0) { build_zero_cst (st); })))))))))) - + (for cmp (unordered ordered unlt unle ungt unge uneq ltgt) /* If the second operand is NaN, the result is constant. */ (simplify @@ -4540,7 +4565,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (wi::to_wide (@1) == -1) (rdiv { build_real (type, dconst1); } @0)))) -/* Narrowing of arithmetic and logical operations. +/* Narrowing of arithmetic and logical operations. These are conceptually similar to the transformations performed for the C/C++ front-ends by shorten_binary_op and shorten_compare. Long @@ -4612,7 +4637,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (convert (bit_and (op (convert:utype @0) (convert:utype @1)) (convert:utype @4)))))))) -/* Transform (@0 < @1 and @0 < @2) to use min, +/* Transform (@0 < @1 and @0 < @2) to use min, (@0 > @1 and @0 > @2) to use max */ (for logic (bit_and bit_and bit_and bit_and bit_ior bit_ior bit_ior bit_ior) op (lt le gt ge lt le gt ge ) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7e73af7..5dbb34e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-10-01 MCC CS + + PR tree-optimization/87261 + * gcc.dg/pr87261.c: New test. + 2018-10-01 Claudiu Zissulescu * gcc.target/arc/tph_addx.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr87261.c b/gcc/testsuite/gcc.dg/pr87261.c new file mode 100644 index 0000000..9b10d03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr87261.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-original" } */ + +int f1 (int a, int b) +{ + return ~(a|b)|(~a&b); +} + +int f2 (int a, int b) +{ + return (a|b)^(a|~b); +} + +/* { dg-final { scan-tree-dump-times "return \\~a;" 2 "original" } } */ + +int f3 (int a, int b) +{ + return ~(a|b)|(a&b); +} + +/* { dg-final { scan-tree-dump "return \\~\\(a \\^ b\\);" "original" } } */ + +int f4 (int a, int b) +{ + return a^b^(~a|b); +} + +/* { dg-final { scan-tree-dump "return \\~b \\| a;" "original" } } */ + +int f5 (int a, int b) +{ + return (a^b)|~(a|b); +} + +/* { dg-final { scan-tree-dump "return \\~\\(a \\& b\\);" "original" } } */ -- 2.7.4