i386: Support read-modify-write memory operands in STV.

This patch enables STV when the first operand of a TImode binary
logic operand (AND, IOR or XOR) is a memory operand, which is commonly
the case with read-modify-write instructions.

A different motivating example from the one given previously is:

__int128 m, p, q;
void foo() {
    m ^= (p & q);
}

Currently with -O2 -mavx the RMW instructions are rejected by STV,
resulting in scalar code:

foo:	movq    p(%rip), %rax
        movq    p+8(%rip), %rdx
        andq    q(%rip), %rax
        andq    q+8(%rip), %rdx
        xorq    %rax, m(%rip)
        xorq    %rdx, m+8(%rip)
        ret

With this patch they become scalar-to-vector candidates:

foo:	vmovdqa p(%rip), %xmm0
        vpand   q(%rip), %xmm0, %xmm0
        vpxor   m(%rip), %xmm0, %xmm0
        vmovdqa %xmm0, m(%rip)
        ret

2024-08-31  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
	* config/i386/i386-features.cc (timode_scalar_to_vector_candidate_p):
	Support the first operand of AND, IOR and XOR being MEM_P, i.e. a
	read-modify-write insn.

gcc/testsuite/ChangeLog
	* gcc.target/i386/movti-2.c: Change dg-options to -Os.
	* gcc.target/i386/movti-4.c: Expected output of original movti-2.c.
This commit is contained in:
Roger Sayle 2024-08-31 14:17:18 -06:00
parent 2ac27bd503
commit bac00c3422
3 changed files with 16 additions and 3 deletions

View file

@ -2330,14 +2330,16 @@ timode_scalar_to_vector_candidate_p (rtx_insn *insn)
|| CONST_SCALAR_INT_P (XEXP (src, 1))
|| timode_mem_p (XEXP (src, 1))))
return true;
return REG_P (XEXP (src, 0))
return (REG_P (XEXP (src, 0))
|| timode_mem_p (XEXP (src, 0)))
&& (REG_P (XEXP (src, 1))
|| CONST_SCALAR_INT_P (XEXP (src, 1))
|| timode_mem_p (XEXP (src, 1)));
case IOR:
case XOR:
return REG_P (XEXP (src, 0))
return (REG_P (XEXP (src, 0))
|| timode_mem_p (XEXP (src, 0)))
&& (REG_P (XEXP (src, 1))
|| CONST_SCALAR_INT_P (XEXP (src, 1))
|| timode_mem_p (XEXP (src, 1)));

View file

@ -1,5 +1,5 @@
/* { dg-do compile { target int128 } } */
/* { dg-options "-O2 -mavx" } */
/* { dg-options "-Os -mavx" } */
__int128 m;
void foo()

View file

@ -0,0 +1,11 @@
/* { dg-do compile { target int128 } } */
/* { dg-options "-O2 -mavx" } */
__int128 m;
void foo()
{
m &= ((__int128)0x0123456789abcdefULL<<64) | 0x0123456789abcdefULL;
}
/* { dg-final { scan-assembler-times "movabsq" 1 } } */
/* { dg-final { scan-assembler-times "vpand" 1 } } */