]> granicus.if.org Git - llvm/commit
[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)
commitbc72642b221bb59499d4635c20318aa6ae7d00df
treefa1ab1477be2d6a860d039e64295cd0f7864002a
parenta1318bfa1bef257a621be021e0ae0ba6fca59fd9
[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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370649 91177308-0d34-0410-b5e6-96231b3b80d8
14 files changed:
lib/Target/X86/X86InstrSSE.td
lib/Target/X86/X86SchedBroadwell.td
lib/Target/X86/X86SchedHaswell.td
lib/Target/X86/X86SchedSandyBridge.td
lib/Target/X86/X86SchedSkylakeClient.td
lib/Target/X86/X86SchedSkylakeServer.td
lib/Target/X86/X86Schedule.td
lib/Target/X86/X86ScheduleAtom.td
lib/Target/X86/X86ScheduleBdVer2.td
lib/Target/X86/X86ScheduleBtVer2.td
lib/Target/X86/X86ScheduleSLM.td
lib/Target/X86/X86ScheduleZnver1.td
test/tools/llvm-mca/X86/BtVer2/resources-avx1.s
test/tools/llvm-mca/X86/BtVer2/resources-sse2.s