]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Small optimization for complex addition, real/imag parts the same
authorAndrew Pinski <quic_apinski@quicinc.com>
Mon, 1 Jul 2024 01:39:07 +0000 (18:39 -0700)
committerAndrew Pinski <quic_apinski@quicinc.com>
Tue, 2 Jul 2024 21:26:51 +0000 (14:26 -0700)
This is just a small optimization for the case where the real and imag
parts are the same when lowering complex addition/subtraction. We only
need to do the addition once when the real and imag parts are the same (on
both sides of the operator). This gets done later on by FRE/PRE/DOM but
having it done soon allows the cabs lowering to remove the sqrt and
just change it to a multiply by a constant.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

* tree-complex.cc (expand_complex_addition): If both
operands have the same real and imag parts, only
add the addition once.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/complex-8.c: New test.

Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
gcc/testsuite/gcc.dg/tree-ssa/complex-8.c [new file with mode: 0644]
gcc/tree-complex.cc

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/complex-8.c b/gcc/testsuite/gcc.dg/tree-ssa/complex-8.c
new file mode 100644 (file)
index 0000000..a9636ff
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-cplxlower1-raw" } */
+
+_Complex double f(double a, double c)
+{
+  _Complex double d = __builtin_complex (a, a);
+  d+=__builtin_complex(c, c);
+  return d;
+}
+
+/* There should only be one plus as (a+c) is still (a+c) */
+/* { dg-final { scan-tree-dump-times "plus_expr, " 1 "cplxlower1" } } */
index 8a879acffca890d26410896120e53b6ff56e91d6..dfebec18ec3daf4ce45c00d5d72149260eee0c7d 100644 (file)
@@ -984,7 +984,12 @@ expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type,
     case PAIR (VARYING, VARYING):
     general:
       rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
-      ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
+      /* (a+ai) + (b+bi) -> (a+b)+(a+b)i
+         small optimization to remove one new statement. */
+      if (operand_equal_p (ar, ai) && operand_equal_p (br, bi))
+       ri = rr;
+      else
+       ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
       break;
 
     default: