[gcc r17-2950] vect: when REALPART/IMAGPART also check their def stmts [PR126593]
Tamar Christina via Gcc-cvs <[email protected]> Tue, 4 Aug 2026 14:36:01 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:987e38794015c2dbb5f16d7641491d3b62680743 commit r17-2950-g987e38794015c2dbb5f16d7641491d3b62680743 Author: Tamar Christina <[email protected]> Date: Tue Aug 4 15:35:26 2026 +0100 vect: when REALPART/IMAGPART also check their def stmts [PR126593] The check in compatible_complex_nodes_p is a bit too loose in that we assumed that when we see a REAL/IMAG pair of statement in a TWO_OPERANDS they must have come from the same defining statement. This is of course too loose and the operands should be checked explicitly. gcc/ChangeLog: PR tree-optimization/126593 * tree-vect-slp-patterns.cc (compatible_complex_nodes_p): Check def stmts of real and imag pairs. gcc/testsuite/ChangeLog: PR tree-optimization/126593 * gcc.target/aarch64/pr126593.c: New test. Diff: --- gcc/testsuite/gcc.target/aarch64/pr126593.c | 37 +++++++++++++++++++++++++++++ gcc/tree-vect-slp-patterns.cc | 4 +++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.target/aarch64/pr126593.c b/gcc/testsuite/gcc.target/aarch64/pr126593.c new file mode 100644 index 000000000000..fce64d4d3393 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr126593.c @@ -0,0 +1,37 @@ +/* { dg-do run { target arm_v8_3a_complex_neon_hw } } */ +/* { dg-require-effective-target aarch64_little_endian } */ +/* { dg-options "-O3 -march=armv8.3-a -ffast-math" } */ + +#define N 64 +_Complex float a[N], b[N], d[N], c[N]; + +__attribute__((noipa)) +void +mix (int n) +{ + for (int i = 0; i < n; i++) + { + __real__ c[i] = __real__ a[i] * __real__ b[i] - __imag__ a[i] * __imag__ d[i]; + __imag__ c[i] = __real__ a[i] * __imag__ b[i] + __imag__ a[i] * __real__ d[i]; + } +} + +int +main (void) +{ + for (int i = 0; i < N; i++) + { + a[i] = 1.0f + 2.0fi; + b[i] = 3.0f + 4.0fi; + d[i] = 5.0f + 6.0fi; + } + + mix (N); + + /* scalar: re = 1*3 - 2*6 = -9, im = 1*4 + 2*5 = 14. + vectorized as a*b: re = -5, im = 10. */ + if (__real__ c[0] != -9.0f || __imag__ c[0] != 14.0f) + __builtin_abort (); + + return 0; +} diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc index c6cf44cfd0d3..f77993100ad1 100644 --- a/gcc/tree-vect-slp-patterns.cc +++ b/gcc/tree-vect-slp-patterns.cc @@ -788,7 +788,9 @@ compatible_complex_nodes_p (slp_compat_nodes_map_t *compat_cache, tree_code acode = gimple_assign_rhs_code (a_stmt); tree_code bcode = gimple_assign_rhs_code (b_stmt); if ((acode == REALPART_EXPR || acode == IMAGPART_EXPR) - && (bcode == REALPART_EXPR || bcode == IMAGPART_EXPR)) + && (bcode == REALPART_EXPR || bcode == IMAGPART_EXPR) + && operand_equal_p (TREE_OPERAND (gimple_assign_rhs1 (a_stmt), 0), + TREE_OPERAND (gimple_assign_rhs1 (b_stmt), 0))) return true; if (acode != bcode)