https://gcc.gnu.org/g:59221dc587f369695d9b0c2f73aedf8458931f0f

commit r15-1508-g59221dc587f369695d9b0c2f73aedf8458931f0f
Author: Andrew Pinski <quic_apin...@quicinc.com>
Date:   Thu Jun 20 15:52:05 2024 -0700

    complex-lowering: Better handling of PAREN_EXPR [PR68855]
    
    When PAREN_EXPR tree code was added in r0-85884-gdedd42d511b6e4,
    a simplified handling was added to complex lowering. Which means
    we would get:
    ```
      _9 = COMPLEX_EXPR <_15, _14>;
      _11 = ((_9));
      _19 = REALPART_EXPR <_11>;
      _20 = IMAGPART_EXPR <_11>;
    ```
    
    In many cases instead of just simply:
    ```
      _19 = ((_15));
      _20 = ((_14));
    ```
    
    So this adds full support for PAREN_EXPR to complex lowering.
    It is handled very similar as NEGATE_EXPR; except creating PAREN_EXPR
    instead of NEGATE_EXPR for the real/imag parts. This allows for
    more optimizations including vectorization, especially with
    -ffast-math.
    gfortran.dg/vect/pr68855.f90 is an example where this could show up.
    It also shows up in SPEC CPU 2006's 465.tonto; though I have not done
    any benchmarking there.
    
    Bootstrapped and tested on x86_64-linux-gnu with no regressions.
    
    gcc/ChangeLog:
    
            PR tree-optimization/68855
            * tree-complex.cc (init_dont_simulate_again): Handle PAREN_EXPR
            like NEGATE_EXPR.
            (complex_propagate::visit_stmt): Likewise.
            (expand_complex_move): Don't handle PAREN_EXPR.
            (expand_complex_paren): New function.
            (expand_complex_operations_1): Handle PAREN_EXPR like
            NEGATE_EXPR. And call expand_complex_paren for PAREN_EXPR.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/vect/pr68855.c: New test.
            * gfortran.dg/vect/pr68855.f90: New test.
    
    Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr68855.c        | 17 +++++++++++++++++
 gcc/testsuite/gfortran.dg/vect/pr68855.f90 | 16 ++++++++++++++++
 gcc/tree-complex.cc                        | 29 +++++++++++++++++++++++++++--
 3 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr68855.c 
b/gcc/testsuite/gcc.dg/vect/pr68855.c
new file mode 100644
index 000000000000..68a3a1cee36e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr68855.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+/* PAREN_EXPR should not cause the vectorization of complex float add to be 
missed. */
+void foo(_Complex float *a, int n)
+{
+  for(int i = 0; i < n; i++)
+  {
+    _Complex float t;
+    t = a[i];
+    t += 6.0;
+    t = __builtin_assoc_barrier(t);
+    a[i] = t;
+  }
+}
diff --git a/gcc/testsuite/gfortran.dg/vect/pr68855.f90 
b/gcc/testsuite/gfortran.dg/vect/pr68855.f90
new file mode 100644
index 000000000000..90d444c86bfa
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/vect/pr68855.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_float }
+
+! { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } }
+! PAREN_EXPR should not cause the vectorization of complex float add to be 
missed.
+
+subroutine foo(a,n)
+
+  complex (kind(1.0)) :: a(*)
+  integer :: i,n
+
+  do i=1,n
+     a(i)=(a(i)+(6.0,1.0))
+  enddo
+  
+end subroutine foo
diff --git a/gcc/tree-complex.cc b/gcc/tree-complex.cc
index 877913972bdd..8a879acffca8 100644
--- a/gcc/tree-complex.cc
+++ b/gcc/tree-complex.cc
@@ -281,6 +281,7 @@ init_dont_simulate_again (void)
 
              case NEGATE_EXPR:
              case CONJ_EXPR:
+             case PAREN_EXPR:
                if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
                  saw_a_complex_op = true;
                break;
@@ -391,6 +392,7 @@ complex_propagate::visit_stmt (gimple *stmt, edge 
*taken_edge_p ATTRIBUTE_UNUSED
       break;
 
     case NEGATE_EXPR:
+    case PAREN_EXPR:
     case CONJ_EXPR:
       new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
       break;
@@ -852,8 +854,7 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type)
          update_complex_components_on_edge (e, lhs, r, i);
        }
       else if (is_gimple_call (stmt)
-              || gimple_has_side_effects (stmt)
-              || gimple_assign_rhs_code (stmt) == PAREN_EXPR)
+              || gimple_has_side_effects (stmt))
        {
          r = build1 (REALPART_EXPR, inner_type, lhs);
          i = build1 (IMAGPART_EXPR, inner_type, lhs);
@@ -1545,6 +1546,25 @@ expand_complex_negation (gimple_stmt_iterator *gsi, tree 
inner_type,
   update_complex_assignment (gsi, rr, ri);
 }
 
+/* Expand complex paren to scalars:
+       ((a)) = ((ar)) + i((ai))
+*/
+
+static void
+expand_complex_paren (gimple_stmt_iterator *gsi, tree inner_type,
+                     tree ar, tree ai)
+{
+  tree rr, ri;
+  gimple_seq stmts = NULL;
+  location_t loc = gimple_location (gsi_stmt (*gsi));
+
+  rr = gimple_build (&stmts, loc, PAREN_EXPR, inner_type, ar);
+  ri = gimple_build (&stmts, loc, PAREN_EXPR, inner_type, ai);
+
+  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+  update_complex_assignment (gsi, rr, ri);
+}
+
 /* Expand complex conjugate to scalars:
        ~a = (ar) + i(-ai)
 */
@@ -1697,6 +1717,7 @@ expand_complex_operations_1 (gimple_stmt_iterator *gsi)
     case ROUND_DIV_EXPR:
     case RDIV_EXPR:
     case NEGATE_EXPR:
+    case PAREN_EXPR:
     case CONJ_EXPR:
       if (TREE_CODE (type) != COMPLEX_TYPE)
        return;
@@ -1815,6 +1836,10 @@ expand_complex_operations_1 (gimple_stmt_iterator *gsi)
       expand_complex_comparison (gsi, ar, ai, br, bi, code);
       break;
 
+    case PAREN_EXPR:
+      expand_complex_paren (gsi, inner_type, ar, ai);
+      break;
+
     default:
       gcc_unreachable ();
     }

Reply via email to