diff --git a/gcc/match.pd b/gcc/match.pd index dd9efb82c59..7db8ce7580f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -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 diff --git a/gcc/testsuite/gcc.dg/pr116700.c b/gcc/testsuite/gcc.dg/pr116700.c new file mode 100644 index 00000000000..a52388249a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr116700.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-48.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-48.c new file mode 100644 index 00000000000..596d7e2c35b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-48.c @@ -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" } } */