https://gcc.gnu.org/g:7c48d6a74693e1c64900f6aa203539ea1ca7b370
commit r17-3200-g7c48d6a74693e1c64900f6aa203539ea1ca7b370 Author: Dipesh Sharma <[email protected]> Date: Sat Aug 8 20:39:17 2026 +0530 match.pd: Fold abs(x) * abs(y) -> abs(x * y) [PR126693] gcc/ChangeLog: PR tree-optimization/126693 * match.pd: Fold abs(x) * abs(y) into abs(x * y). gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/mult-abs-3.c: New test. * gcc.dg/tree-ssa/mult-abs-4.c: New test. * gcc.dg/tree-ssa/mult-abs-5.c: New test. Diff: --- gcc/match.pd | 10 ++++++++++ gcc/testsuite/gcc.dg/tree-ssa/mult-abs-3.c | 17 ++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/mult-abs-4.c | 32 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/mult-abs-5.c | 7 +++++++ 4 files changed, 66 insertions(+) diff --git a/gcc/match.pd b/gcc/match.pd index 50e731770228..beea45357e22 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1284,6 +1284,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (mult (absu@1 @0) @1) (mult (convert@2 @0) @2)) +/* abs(x) * abs(y) -> abs(x * y). */ +(simplify + (mult (abs:s @0) (abs:s @1)) + (if ((FLOAT_TYPE_P (type) + && !HONOR_SIGN_DEPENDENT_ROUNDING (type)) + || (ANY_INTEGRAL_TYPE_P (type) + && TYPE_OVERFLOW_UNDEFINED (type) + && !TYPE_OVERFLOW_SANITIZED (type))) + (abs (mult @0 @1)))) + #if GIMPLE /* Simplify SAD(x, x, acc) -> acc since the absolute difference is zero. */ (simplify diff --git a/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-3.c b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-3.c new file mode 100644 index 000000000000..121b437165ab --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-3.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target c99_runtime } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include <stdlib.h> + +double f (double x, double y) { return __builtin_fabs (x) * __builtin_fabs (y); } +float g (float x, float y) { return __builtin_fabsf (x) * __builtin_fabsf (y); } +int h (int x, int y) { return __builtin_abs (x) * __builtin_abs (y); } +long i (long x, long y) { return __builtin_labs (x) * __builtin_labs (y); } +long long j (long long x, long long y) { return __builtin_llabs (x) * __builtin_llabs (y); } + +int k (int x, int y) { return abs (x) * abs (y); } +long l (long x, long y) { return labs (x) * labs (y); } +long long m (long long x, long long y) { return llabs (x) * llabs (y); } + +/* { dg-final { scan-tree-dump-times "ABS_EXPR" 8 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-4.c b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-4.c new file mode 100644 index 000000000000..4979dfd5207c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +double __attribute__((optimize ("-frounding-math"))) +frnd (double x, double y) +{ + return __builtin_fabs (x) * __builtin_fabs (y); +} + +int __attribute__((optimize ("-fwrapv"))) +wrap (int x, int y) +{ + return __builtin_abs (x) * __builtin_abs (y); +} + +int __attribute__((optimize ("-ftrapv"))) +trap (int x, int y) +{ + return __builtin_abs (x) * __builtin_abs (y); +} + +int gx, gy; +int shared (int x, int y) +{ + int ax = __builtin_abs (x); + int ay = __builtin_abs (y); + gx = ax; + gy = ay; + return ax * ay; +} + +/* { dg-final { scan-tree-dump-times "ABS_EXPR" 8 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-5.c b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-5.c new file mode 100644 index 000000000000..860b931c376a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/mult-abs-5.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsanitize=signed-integer-overflow -fdump-tree-optimized" } */ + +int f (int x, int y) { return __builtin_abs (x) * __builtin_abs (y); } +long g (long x, long y) { return __builtin_labs (x) * __builtin_labs (y); } + +/* { dg-final { scan-tree-dump-times "ABS_EXPR" 4 "optimized" } } */
