diff options
author | Andrew Pinski <quic_apinski@quicinc.com> | 2024-06-20 15:52:05 -0700 |
---|---|---|
committer | Andrew Pinski <quic_apinski@quicinc.com> | 2024-06-20 23:38:32 -0700 |
commit | 59221dc587f369695d9b0c2f73aedf8458931f0f (patch) | |
tree | 4f821ac13a6d57f610339e869609e139ac38788b | |
parent | 1f974c3a24b76e25a2b7f31a6c7f4aee93a9eaab (diff) | |
download | gcc-59221dc587f369695d9b0c2f73aedf8458931f0f.zip gcc-59221dc587f369695d9b0c2f73aedf8458931f0f.tar.gz gcc-59221dc587f369695d9b0c2f73aedf8458931f0f.tar.bz2 |
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_apinski@quicinc.com>
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr68855.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/vect/pr68855.f90 | 16 | ||||
-rw-r--r-- | 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 0000000..68a3a1c --- /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 0000000..90d444c --- /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 8779139..8a879ac 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 (); } |