https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126000

            Bug ID: 126000
           Summary: [x86] Missed optimization: use EVEX encoding with
                    compressed disp8 (disp8*N) instead of VEX+disp32
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vekumar at gcc dot gnu.org
  Target Milestone: ---

For SSE/AVX instructions that have both a VEX and an EVEX form, GCC always
emits
the VEX encoding for the low registers (xmm0..15). When the memory operand uses
a constant displacement that does NOT fit in a signed 8-bit field, VEX is
forced
to spend a full 4-byte disp32.

EVEX can encode the same access in fewer bytes using the
compressed-displacement
form (disp8*N): if the displacement is a multiple of the operand's CD8 scale N
and the scaled value fits in a signed byte, only a 1-byte displacement is
needed.
This more than offsets the larger EVEX prefix, so the overall instruction is
shorter.

--snip t.c--
 void sink(double *);
  double f(void)
  {
    double buf[160];
    sink(buf);                              
    return buf[89] + buf[100] + buf[120];  
  }
--snip--

Compile:
  gcc -O2 -mavx512vl -mavx512f -c t.c -o t.o && objdump -d t.o

Actual (VEX, 9 bytes each):
  c5 fb 10 84 24 c8 02 00 00   vmovsd 0x2c8(%rsp),%xmm0
  c5 fb 58 84 24 20 03 00 00   vaddsd 0x320(%rsp),%xmm0,%xmm0
  c5 fb 58 84 24 c0 03 00 00   vaddsd 0x3c0(%rsp),%xmm0,%xmm0

Possible (EVEX with disp8*N, N=8; 8 bytes each):
  62 f1 ff 08 10 44 24 59      vmovsd 0x2c8(%rsp),%xmm0       ; 0x2c8 = 8*0x59
  62 f1 ff 08 58 44 24 64      vaddsd 0x320(%rsp),%xmm0,%xmm0 ; 0x320 = 8*0x64
  62 f1 ff 08 58 44 24 78      vaddsd 0x3c0(%rsp),%xmm0,%xmm0 ; 0x3c0 = 8*0x78

Savings: 1 byte per instruction (3 bytes in this small function).

Reply via email to