https://gcc.gnu.org/g:d5998d61eef27c98baa0307b2302e2475b9a3d64
commit r16-9125-gd5998d61eef27c98baa0307b2302e2475b9a3d64 Author: Tamar Christina <[email protected]> Date: Wed Jun 3 09:42:15 2026 +0100 vect: gate COMPLEX_MUL on FP_CONTRACT_FAST [PR125431] The checks for FP_CONTRACT_FAST were in the wrong place for complex_mul. The location it was in would only block FMA but not MUL. It would also not really reject the forming of the FMA, it would just create an invalid collection of nodes which would fail analysis later on. However complex multiplication is also a contraction, since it's doing real = a*c - b*d imag = a*d + b*c This moves the checks up to earliest possible location and actually just returns and adds the missing check for FMS. gcc/ChangeLog: PR tree-optimization/125431 * tree-vect-slp-patterns.cc (complex_mul_pattern::matches, complex_fms_pattern::matches): Gate on FP contraction. gcc/testsuite/ChangeLog: PR tree-optimization/125431 * gfortran.dg/vect/pr125431.f90: New test. (cherry picked from commit 074ed30c2382f163b74e98baa4c242a721c57519) Diff: --- gcc/testsuite/gfortran.dg/vect/pr125431.f90 | 16 ++++++++++++++++ gcc/tree-vect-slp-patterns.cc | 15 +++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gfortran.dg/vect/pr125431.f90 b/gcc/testsuite/gfortran.dg/vect/pr125431.f90 new file mode 100644 index 000000000000..fe11b5eface9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr125431.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-additional-options "-O2 -ffp-contract=off" } +! { dg-additional-options "-march=armv8.3-a" { target { aarch64*-*-* } } } + +subroutine foo(a,b,c) + + complex :: a(6,6) + complex :: b(6,6) + complex :: c(6,6) + + c = MATMUL(a, b) + +end subroutine foo + +! { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { vect_float } } } } +! { dg-final { scan-tree-dump-not "Found COMPLEX_MUL" "vect" } } diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc index 0976258a36d0..9eb1478c4cc5 100644 --- a/gcc/tree-vect-slp-patterns.cc +++ b/gcc/tree-vect-slp-patterns.cc @@ -1043,6 +1043,11 @@ complex_mul_pattern::matches (complex_operation_t op, if (op != MINUS_PLUS) return IFN_LAST; + /* It's only valid to form FMAs and MUL with -ffp-contract=fast. */ + if (flag_fp_contract_mode != FP_CONTRACT_FAST + && FLOAT_TYPE_P (SLP_TREE_VECTYPE (*node))) + return IFN_LAST; + auto childs = *ops; auto l0node = SLP_TREE_CHILDREN (childs[0]); @@ -1055,11 +1060,8 @@ complex_mul_pattern::matches (complex_operation_t op, auto_vec<slp_tree> left_op, right_op; slp_tree add0 = NULL; - /* Check if we may be a multiply add. It's only valid to form FMAs - with -ffp-contract=fast. */ + /* Check if we may be a multiply add. */ if (!mul0 - && (flag_fp_contract_mode == FP_CONTRACT_FAST - || !FLOAT_TYPE_P (SLP_TREE_VECTYPE (*node))) && vect_match_expression_p (l0node[0], PLUS_EXPR)) { auto vals = SLP_TREE_CHILDREN (l0node[0]); @@ -1290,6 +1292,11 @@ complex_fms_pattern::matches (complex_operation_t op, if (!vect_match_expression_p (root, MINUS_EXPR)) return IFN_LAST; + /* It's only valid to form FMSs with -ffp-contract=fast. */ + if (flag_fp_contract_mode != FP_CONTRACT_FAST + && FLOAT_TYPE_P (SLP_TREE_VECTYPE (*ref_node))) + return IFN_LAST; + /* TODO: Support invariants here, with the new layout CADD now can match before we get a chance to try CFMS. */ auto nodes = SLP_TREE_CHILDREN (root);
