[PATCH] PR tree-optimization/126693: Fold abs(x) * abs(y) -> abs(x * y).

Dipesh Sharma <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
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 ?


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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.