Re: [PATCH] PR tree-optimization/126693: Fold abs(x) * abs(y) -> abs(x * y).
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CALvbMcAAF8DD-LfFjwY48XHKMqO50zJSP_nHa+xNORCv01UeNg@mail.gmail.com> |
On Mon, Aug 10, 2026 at 6:50 AM Dipesh Sharma <[email protected]> wrote: > > Hi all, > > This patch addresses the issue https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126693. > > The optimization is not valid for the following cases: > > - fp with -frounding-math. > - Integers with wrapping arithmetic and signed integer overflow. > - values to be folded must have single use otherwise we may end up adding an extra ABS_EXPR. > > e.g. > int gx, gy, mul; > void f (int x, int y) > { > int ax = __builtin_abs (x); > int ay = __builtin_abs (y); > mul = ax * ay; > gx = ax; // use of ax > gy = ay; // use of ay > } > > regtested and bootstraped on x86_64-linux-gnu. ok for trunk ? Ok. > > > 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. > --- > 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(+) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/mult-abs-3.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/mult-abs-4.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/mult-abs-5.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index a2a48e1b475..379fa98a692 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -1254,6 +1254,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 00000000000..2bebafc65b0 > --- /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 00000000000..4979dfd5207 > --- /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 00000000000..860b931c376 > --- /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" } } */ > -- > 2.34.1 >