Message ID | 20240621023439.1645017-1-quic_apinski@quicinc.com |
---|---|
State | New |
Headers | show |
Series | complex-lowering: Better handling of PAREN_EXPR [PR68855] | expand |
> Am 21.06.2024 um 04:35 schrieb Andrew Pinski <quic_apinski@quicinc.com>: > > 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. Ok Thanks, Richard > 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> > --- > 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(-) > create mode 100644 gcc/testsuite/gcc.dg/vect/pr68855.c > create mode 100644 gcc/testsuite/gfortran.dg/vect/pr68855.f90 > > diff --git a/gcc/testsuite/gcc.dg/vect/pr68855.c b/gcc/testsuite/gcc.dg/vect/pr68855.c > new file mode 100644 > index 00000000000..68a3a1cee36 > --- /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 00000000000..90d444c86bf > --- /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 877913972bd..8a879acffca 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 (); > } > -- > 2.43.0 >
diff --git a/gcc/testsuite/gcc.dg/vect/pr68855.c b/gcc/testsuite/gcc.dg/vect/pr68855.c new file mode 100644 index 00000000000..68a3a1cee36 --- /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 00000000000..90d444c86bf --- /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 877913972bd..8a879acffca 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 (); }
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> --- 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(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr68855.c create mode 100644 gcc/testsuite/gfortran.dg/vect/pr68855.f90