mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
match: Optimize A > B ? ABS(A) : B to MAX(A, B) when B >= 0 [PR116700]
When B is known to be non-negative and A > B, A must be positive, so ABS(A) == A. The whole expression (A > B ? ABS(A) : B) then simplifies to MAX(A, B). This is caught at -O2 via VRP, but at -O1 phiopt1 produces ABS_EXPR and no later pass simplifies it. PR tree-optimization/116700 gcc/ChangeLog: * match.pd: (A > B ? ABS(A) : B -> MAX(A, B)): New pattern for non-negative B. gcc/testsuite/ChangeLog: * gcc.dg/pr116700.c: New test. * gcc.dg/tree-ssa/phi-opt-48.c: New test. Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
This commit is contained in:
committed by
Andrew Pinski
parent
1e59a869af
commit
e0c4c4cb02
@@ -7276,6 +7276,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
(if (INTEGRAL_TYPE_P (type))
|
||||
@3))
|
||||
|
||||
/* A > B ? ABS(A) : B -> MAX(A, B) when B is non-negative.
|
||||
When A > B >= 0, A is positive so ABS(A) = A = MAX(A, B).
|
||||
When A <= B, the result is B = MAX(A, B). */
|
||||
(for cmp (gt ge)
|
||||
(simplify
|
||||
(cond (cmp:c @0 tree_expr_nonnegative_p@1) (abs @0) @1)
|
||||
(if (INTEGRAL_TYPE_P (type))
|
||||
(max @0 @1))))
|
||||
|
||||
/* (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
|
||||
|
||||
13
gcc/testsuite/gcc.dg/pr116700.c
Normal file
13
gcc/testsuite/gcc.dg/pr116700.c
Normal file
@@ -0,0 +1,13 @@
|
||||
/* PR tree-optimization/116700 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fdump-tree-phiopt1" } */
|
||||
|
||||
int f(unsigned char a, int b, int c)
|
||||
{
|
||||
int t = a;
|
||||
if (c > t) t = (c > 0 ? c : -c);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "MAX_EXPR" "phiopt1" } } */
|
||||
/* { dg-final { scan-tree-dump-not "ABS_EXPR" "phiopt1" } } */
|
||||
25
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-48.c
Normal file
25
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-48.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fdump-tree-phiopt1" } */
|
||||
|
||||
/* Test that (A > B) ? ABS(A) : B is simplified to MAX(A, B)
|
||||
when B is known to be non-negative. */
|
||||
|
||||
int f(unsigned char a, int b, int c)
|
||||
{
|
||||
int t = a;
|
||||
if (c > t)
|
||||
t = (c > 0 ? c : -c);
|
||||
return t;
|
||||
}
|
||||
|
||||
int f1(unsigned char a, int b, int c)
|
||||
{
|
||||
int t = a;
|
||||
if (c > t) return (c > 0 ? c : -c);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Both functions should be converted to MAX_EXPR by phiopt1. */
|
||||
/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt1" } } */
|
||||
/* { dg-final { scan-tree-dump-not "ABS_EXPR" "phiopt1" } } */
|
||||
/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */
|
||||
Reference in New Issue
Block a user