mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-27 05:44:15 +08:00
match: a CMP nonnegative ? a : ABS<a>
simplified to just ABS<a>
[PR112392]
We can optimize `a == nonnegative ? a : ABS<a>`, `a > nonnegative ? a : ABS<a>` and `a >= nonnegative ? a : ABS<a>` into `ABS<a>`. This allows removal of some extra comparison and extra conditional moves in some cases. I don't remember where I had found though but it is simple to add so let's add it. Bootstrapped and tested on x86_64-linux-gnu with no regressions. Note I have a secondary pattern for the equal case as either a or nonnegative could be used. PR tree-optimization/112392 gcc/ChangeLog: * match.pd (`x CMP nonnegative ? x : ABS<x>`): New pattern; where CMP is ==, > and >=. (`x CMP nonnegative@y ? y : ABS<x>`): New pattern. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/phi-opt-41.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
This commit is contained in:
parent
f4b86ab09d
commit
5726de79e2
15
gcc/match.pd
15
gcc/match.pd
@ -5876,6 +5876,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
(convert (absu:utype @0)))
|
||||
@3))))
|
||||
|
||||
/* X > Positive ? X : ABS(X) -> ABS(X) */
|
||||
/* X >= Positive ? X : ABS(X) -> ABS(X) */
|
||||
/* X == Positive ? X : ABS(X) -> ABS(X) */
|
||||
(for cmp (eq gt ge)
|
||||
(simplify
|
||||
(cond (cmp:c @0 tree_expr_nonnegative_p@1) @0 (abs@3 @0))
|
||||
(if (INTEGRAL_TYPE_P (type))
|
||||
@3)))
|
||||
|
||||
/* X == Positive ? Positive : ABS(X) -> ABS(X) */
|
||||
(simplify
|
||||
(cond (eq:c @0 tree_expr_nonnegative_p@1) @1 (abs@3 @0))
|
||||
(if (INTEGRAL_TYPE_P (type))
|
||||
@3))
|
||||
|
||||
/* (X + 1) > Y ? -X : 1 simplifies to X >= Y ? -X : 1 when
|
||||
X is unsigned, as when X + 1 overflows, X is -1, so -X == 1. */
|
||||
(simplify
|
||||
|
34
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c
Normal file
34
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fdump-tree-phiopt1" } */
|
||||
/* PR tree-optimization/112392 */
|
||||
|
||||
int feq_1(int a, unsigned char b)
|
||||
{
|
||||
int absb = b;
|
||||
if (a == absb) return absb;
|
||||
return a > 0 ? a : -a;
|
||||
}
|
||||
int feq_2(int a, unsigned char b)
|
||||
{
|
||||
int absb = b;
|
||||
if (a == absb) return a;
|
||||
return a > 0 ? a : -a;
|
||||
}
|
||||
|
||||
int fgt(int a, unsigned char b)
|
||||
{
|
||||
int absb = b;
|
||||
if (a > absb) return a;
|
||||
return a > 0 ? a : -a;
|
||||
}
|
||||
|
||||
int fge(int a, unsigned char b)
|
||||
{
|
||||
int absb = b;
|
||||
if (a >= absb) return a;
|
||||
return a > 0 ? a : -a;
|
||||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */
|
||||
/* { dg-final { scan-tree-dump-times "ABS_EXPR <" 4 "phiopt1" } } */
|
Loading…
Reference in New Issue
Block a user