[WoA] Use fences for sequentially consistent stores/writes
authorNadeem, Usman <mnadeem@quicinc.com>
Mon, 23 Jan 2023 19:13:58 +0000 (11:13 -0800)
committerNadeem, Usman <mnadeem@quicinc.com>
Tue, 24 Jan 2023 00:09:11 +0000 (16:09 -0800)
commitc9821abfc023fba684c8ef8589c49cba8083f579
tree18828b1de1cbb77fe5ebb566baaf3a965494c8c5
parenta6a4fe203f3cd8cdae2a7b23b1993718021cb43a
[WoA] Use fences for sequentially consistent stores/writes

LLVM currently uses LDAR/STLR and variants for acquire/release
as well as seq_cst operations. This is fine as long as all code uses
this convention.

Normally LDAR/STLR act as one way barriers but when used in
combination they provide a sequentially consistent model. i.e.
when an LDAR appears after an STLR in program order the STLR
acts as a two way fence and the store will be observed before
the load.

The problem is that normal loads (unlike ldar), when they appear
after the STLR can be observed before STLR (if my understanding
is correct). Possibly providing weaker than expected guarantees if
they are used for ordered atomic operations.

Unfortunately in Microsoft Visual Studio STL seq_cst ld/st are
implemented using normal load/stores and explicit fences:
dmb ish + str + dmb ish
ldr + dmb ish

This patch uses fences for MSVC target whenever we write to the
memory in a sequentially consistent way so that we don't rely on
the assumptions that just using LDAR/STLR will give us sequentially
consistent ordering.

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

Change-Id: I48f3500ff8ec89677c9f089ce58181bd139bc68a
llvm/include/llvm/CodeGen/TargetLowering.h
llvm/lib/CodeGen/AtomicExpandPass.cpp
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/lib/Target/AArch64/AArch64ISelLowering.h
llvm/test/CodeGen/AArch64/atomic-ops-msvc.ll