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>
This commit is contained in:
Andrew Pinski 2023-12-31 16:38:30 -08:00
parent 589781c1d2
commit 97def769e6
3 changed files with 37 additions and 3 deletions

View file

@ -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;
}

View file

@ -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>

View file

@ -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" } } */