vect: Fix operand swapping on complex multiplication detection [PR122408]
For
SUBROUTINE a( j, b, c, d )
!GCC$ ATTRIBUTES noinline :: a
COMPLEX*16 b
COMPLEX*16 c( * ), d( * )
DO k = 1, j
c( k ) = - b * CONJG( d( k ) )
END DO
END
we incorrectly generate .IFN_COMPLEX_MUL instead of .IFN_COMPLEX_MUL_CONJ.
The issue happens because in the call to vect_validate_multiplication the
operand vectors are passed by reference and so the stripping of the NEGATE_EXPR
after matching modifies the input vector. If validation fail we flip the
operands and try again. But we've already stipped the negates and so if we
match we would match a normal multiply.
This fixes the API by marking the operands as const and instead pass an explicit
output vec that's to be used. This also reduces the number of copies we were
doing.
With this we now correctly detect .IFN_COMPLEX_MUL_CONJ. Weirdly enough I
couldn't reproduce this with any C example because they get reassociated
differently and always succeed on the first attempt. Fortran is easy to
trigger though so new fortran tests added.
gcc/ChangeLog:
PR tree-optimization/122408
* tree-vect-slp-patterns.cc (vect_validate_multiplication): Cleanup and
document interface.
(complex_mul_pattern::matches, complex_fms_pattern::matches): Update to
new interface.
gcc/testsuite/ChangeLog:
PR tree-optimization/122408
* gfortran.target/aarch64/pr122408_1.f90: New test.
* gfortran.target/aarch64/pr122408_2.f90: New test.