diff options
author | Andrew Pinski <quic_apinski@quicinc.com> | 2023-12-31 16:38:30 -0800 |
---|---|---|
committer | Andrew Pinski <quic_apinski@quicinc.com> | 2024-01-04 12:51:50 -0800 |
commit | 97def769e6b28832f5ba4087d6fcdd44e18bf005 (patch) | |
tree | 0d4b7a546e1f52ba454c0cda8f79911b2195f7b0 | |
parent | 589781c1d266290e6a84fdb65fc979354d67dbac (diff) | |
download | gcc-97def769e6b28832f5ba4087d6fcdd44e18bf005.zip gcc-97def769e6b28832f5ba4087d6fcdd44e18bf005.tar.gz gcc-97def769e6b28832f5ba4087d6fcdd44e18bf005.tar.bz2 |
Match: Improve inverted_equal_p for bool and `^` and `==` [PR113186]
For boolean types, `a ^ b` is a valid form for `a != b`. This means for
gimple_bitwise_inverted_equal_p, we catch some inverted value forms. This
patch extends inverted_equal_p to allow matching of `^` with the
corresponding `==`. Note in the testcase provided we used to optimize
in GCC 12 to just `return 0` where `a == b` was used,
this allows us to do that again.
Bootstrapped and tested on x86_64-linux-gnu with no regressions.
PR tree-optimization/113186
gcc/ChangeLog:
* gimple-match-head.cc (gimple_bitwise_inverted_equal_p):
Match `^` with the `==` for 1bit integral types.
* match.pd (maybe_cmp): Allow for bit_xor for 1bit
integral types.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/bitops-bool-1.c: New test.
Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
-rw-r--r-- | gcc/gimple-match-head.cc | 20 | ||||
-rw-r--r-- | gcc/match.pd | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/bitops-bool-1.c | 14 |
3 files changed, 37 insertions, 3 deletions
diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc index bcc2d63..5f8a1a1 100644 --- a/gcc/gimple-match-head.cc +++ b/gcc/gimple-match-head.cc @@ -333,9 +333,23 @@ gimple_bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp, tree (*va if (!operand_equal_p (op11, op21)) return false; wascmp = true; - if (invert_tree_comparison (gimple_assign_rhs_code (a1), - HONOR_NANS (op10)) - == gimple_assign_rhs_code (a2)) + tree_code ac1 = gimple_assign_rhs_code (a1); + tree_code ac2 = gimple_assign_rhs_code (a2); + /* Match `^` against `==` but this should only + happen when the type is a 1bit precision integer. */ + if (ac1 == BIT_XOR_EXPR) + { + tree type = TREE_TYPE (newexpr1); + gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1); + return ac2 == EQ_EXPR; + } + if (ac2 == BIT_XOR_EXPR) + { + tree type = TREE_TYPE (newexpr1); + gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1); + return ac1 == EQ_EXPR; + } + if (invert_tree_comparison (ac1, HONOR_NANS (op10)) == ac2) return true; return false; } diff --git a/gcc/match.pd b/gcc/match.pd index 87e2fab..7b4b15a 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -182,6 +182,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (convert (cmp@0 @1 @2)) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))))) ) +/* `a ^ b` is another form of `a != b` when the type + is a 1bit precission integer. */ +(match (maybe_cmp @0) + (bit_xor@0 @1 @2) + (if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) == 1))) #endif /* Transform likes of (char) ABS_EXPR <(int) x> into (char) ABSU_EXPR <x> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-bool-1.c b/gcc/testsuite/gcc.dg/tree-ssa/bitops-bool-1.c new file mode 100644 index 0000000..8b43afb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/bitops-bool-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized -fdump-tree-forwprop1" } */ +/* PR tree-optimized/113186 */ + +_Bool f(_Bool a, _Bool c) +{ + _Bool b = (a^c); + _Bool d = (a^!c); + return b & d; +} + +/* This function should be optimized to return 0; */ +/* { dg-final { scan-tree-dump "return 0" "optimized" } } */ +/* { dg-final { scan-tree-dump "return 0" "forwprop1" } } */ |