As mentioned in PR 110202, GCC may be presented with input where control
word of the VPTERNLOG intrinsic implies that some of its operands do not
affect the result. In that case, we can eliminate redundant operands
of the instruction by substituting any other operand in their place.
This removes false dependencies.
For instance, instead of (252 = 0xfc = _MM_TERNLOG_A | _MM_TERNLOG_B)
vpternlogq $252, %zmm2, %zmm1, %zmm0
emit
vpternlogq $252, %zmm0, %zmm1, %zmm0
When VPTERNLOG is invariant w.r.t first and second operands, and the
third operand is memory, load memory into the output operand first, i.e.
instead of (85 = 0x55 = ~_MM_TERNLOG_C)
PR target/110202
* config/i386/i386-protos.h
(vpternlog_redundant_operand_mask): Declare.
(substitute_vpternlog_operands): Declare.
* config/i386/i386.cc
(vpternlog_redundant_operand_mask): New helper.
(substitute_vpternlog_operands): New function. Use them...
* config/i386/sse.md: ... here in new VPTERNLOG define_splits.
gcc/testsuite/ChangeLog:
PR target/110202
* gcc.target/i386/invariant-ternlog-1.c: New test.
* gcc.target/i386/invariant-ternlog-2.c: New test.