match: Optimize max(a,b) == 0
to (a|b) == 0
for unsigned [PR115275]
For unsigned types, you can optimize `max<a,b> == 0` into `(a|b) == 0` (that is both have to be zero). A similar thing happens for `!= 0`. This optimization fixes the missed optimization (g++.dg/tree-ssa/pr115275.C) that was reported exposed by adding phiprop early. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/115275 gcc/ChangeLog: * match.pd (umax(a,b) ==/!= 0): New pattern. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/pr115275.C: New test. * gcc.dg/tree-ssa/max_eqne-1.c: New test. * gcc.dg/tree-ssa/max_eqne-2.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
This commit is contained in:
parent
5eadc67336
commit
b085fc9965
4 changed files with 83 additions and 0 deletions
|
@ -4795,6 +4795,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
(cmp (minmax @0 INTEGER_CST@1) INTEGER_CST@2)
|
||||
(comb (cmp @0 @2) (cmp @1 @2))))
|
||||
|
||||
/* MAX (A, B) == 0 -> (A|B) == 0 iff unsigned.
|
||||
MAX (A, B) != 0 -> (A|B) != 0 iff unsigned. */
|
||||
(for cmp (eq ne)
|
||||
(simplify
|
||||
(cmp (max @0 @1) integer_zerop@2)
|
||||
(if (TYPE_UNSIGNED (TREE_TYPE (@0)))
|
||||
(cmp (bit_ior @0 @1) @2))))
|
||||
|
||||
/* Undo fancy ways of writing max/min or other ?: expressions, like
|
||||
a - ((a - b) & -(a < b)) and a - (a - b) * (a < b) into (a < b) ? b : a.
|
||||
People normally use ?: and that is what we actually try to optimize. */
|
||||
|
|
36
gcc/testsuite/g++.dg/tree-ssa/pr115275.C
Normal file
36
gcc/testsuite/g++.dg/tree-ssa/pr115275.C
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
|
||||
/* PR tree-optimization/115275 */
|
||||
|
||||
template<class T>
|
||||
inline const T &
|
||||
min(const T &a, const T &b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline const T &
|
||||
max(const T &a, const T &b)
|
||||
{
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
|
||||
unsigned short m, a, b;
|
||||
void removeme ();
|
||||
void fn(unsigned short f) {
|
||||
if(
|
||||
(min(max(f, a) ? f : 0U, 84991U))
|
||||
-
|
||||
(min(max(f, b) ? f : 0U, 84991U))
|
||||
)
|
||||
{
|
||||
removeme();
|
||||
}
|
||||
}
|
||||
|
||||
/* removeme call should be optimized out. */
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "removeme " "optimized" } } */
|
20
gcc/testsuite/gcc.dg/tree-ssa/max_eqne-1.c
Normal file
20
gcc/testsuite/gcc.dg/tree-ssa/max_eqne-1.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
|
||||
|
||||
/* PR tree-optimization/115275 */
|
||||
|
||||
unsigned maxne(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned t = a > b ? a : b;
|
||||
return t != 0;
|
||||
}
|
||||
unsigned maxeq(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned t = a > b ? a : b;
|
||||
return t == 0;
|
||||
}
|
||||
/* `max(a,b) == 0` should be optimized to `(a|b) == 0` for unsigned types. */
|
||||
/* { dg-final { scan-tree-dump-not "max_expr, " "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "bit_ior_expr, " 2 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "eq_expr, " 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "ne_expr, " 1 "optimized" } } */
|
19
gcc/testsuite/gcc.dg/tree-ssa/max_eqne-2.c
Normal file
19
gcc/testsuite/gcc.dg/tree-ssa/max_eqne-2.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
|
||||
|
||||
/* PR tree-optimization/115275 */
|
||||
signed maxne(signed a, signed b)
|
||||
{
|
||||
unsigned t = a > b ? a : b;
|
||||
return t != 0;
|
||||
}
|
||||
signed maxeq(signed a, signed b)
|
||||
{
|
||||
unsigned t = a > b ? a : b;
|
||||
return t == 0;
|
||||
}
|
||||
/* For signed types, `max(a,b) == 0` should not optimized to `(a|b) == 0`. */
|
||||
/* { dg-final { scan-tree-dump-times "max_expr, " 2 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-not "bit_ior_expr, " "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "eq_expr, " 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "ne_expr, " 1 "optimized" } } */
|
Loading…
Add table
Reference in a new issue