[X86][BtVer2] Fix latency and throughput of conditional SIMD store instructions.
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Mon, 2 Sep 2019 12:32:28 +0000 (12:32 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Mon, 2 Sep 2019 12:32:28 +0000 (12:32 +0000)
commit528f68144b7eca9a85d14ac6be96ca2fde4d654d
treefb93c89022ee6848cd365df33485dee8fba304cb
parent22493f66f168cf3cf8512e42b4ffb32f3f30b949
[X86][BtVer2] Fix latency and throughput of conditional SIMD store instructions.

On BtVer2 conditional SIMD stores are heavily microcoded.
The latency is directly proportional to the number of packed elements extracted
from the input vector. Also, according to micro-benchmarks, most of the
computation seems to be done in the integer unit.

Only a minority of the uOPs is executed by the FPU. The observed behaviour on
the FPU looks similar to this:
 - The input MASK value is moved to the Integer Unit
   -- [ a VMOVMSK-like uOP-executed on JFPU0].
 - In parallel, each element of the input XMM/YMM is extracted and then sent to
   the IntegerUnit through JFPU1.

As expected, a (conditional) store is executed for every extracted element.
Interestingly, a (speculative) load is executed for every extracted element too.
It is as-if a "LOAD - BIT_EXTRACT- CMOV" sequence of uOPs is repeated by the
integer unit for every contionally stored element.
VMASKMOVDQU is a special case: the number of speculative loads is always 2
(presumably, one load per quadword). That means, extra shifts and masking is
performed on (one of) the loaded quadwords before each conditional store (that
also explains the big number of non-FP uOPs retired).

This patch replaces the existing writes for conditional SIMD stores (i.e.
WriteFMaskedStore, and WriteFMaskedStoreY) with the following new writes:

  WriteFMaskedStore32  [ XMM Packed Single ]
  WriteFMaskedStore32Y [ YMM Packed Single ]
  WriteFMaskedStore64  [ XMM Packed Double ]
  WriteFMaskedStore64Y [ YMM Packed Double ]

Added a wrapper class named X86SchedWriteMaskMove in X86Schedule.td to describe
both RM and MR variants for conditional SIMD moves in a single tablegen
definition.
Instances of that class are then passed in input to multiclass avx_movmask_rm
when constructing MASKMOVPS/PD definitions.

Since this patch introduces new writes, I had to update all the X86 scheduling
models.

Differential Revision: https://reviews.llvm.org/D66801

llvm-svn: 370649
14 files changed:
llvm/lib/Target/X86/X86InstrSSE.td
llvm/lib/Target/X86/X86SchedBroadwell.td
llvm/lib/Target/X86/X86SchedHaswell.td
llvm/lib/Target/X86/X86SchedSandyBridge.td
llvm/lib/Target/X86/X86SchedSkylakeClient.td
llvm/lib/Target/X86/X86SchedSkylakeServer.td
llvm/lib/Target/X86/X86Schedule.td
llvm/lib/Target/X86/X86ScheduleAtom.td
llvm/lib/Target/X86/X86ScheduleBdVer2.td
llvm/lib/Target/X86/X86ScheduleBtVer2.td
llvm/lib/Target/X86/X86ScheduleSLM.td
llvm/lib/Target/X86/X86ScheduleZnver1.td
llvm/test/tools/llvm-mca/X86/BtVer2/resources-avx1.s
llvm/test/tools/llvm-mca/X86/BtVer2/resources-sse2.s