aarch64: Remove early clobber from ATOMIC_LDOP scratch
authorRichard Henderson <richard.henderson@linaro.org>
Wed, 31 Oct 2018 23:11:22 +0000 (23:11 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 31 Oct 2018 23:11:22 +0000 (16:11 -0700)
* config/aarch64/atomics.md (aarch64_atomic_<ATOMIC_LDOP><ALLI>_lse):
The scratch register need not be early-clobber.  Document the reason
why we cannot use ST<OP>.

From-SVN: r265703

gcc/ChangeLog
gcc/config/aarch64/atomics.md

index 8361165..8510ddd 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-31  Richard Henderson  <richard.henderson@linaro.org>
+
+       * config/aarch64/atomics.md (aarch64_atomic_<ATOMIC_LDOP><ALLI>_lse):
+       scratch register need not be early-clobber.  Document the reason
+       why we cannot use ST<OP>.
+
 2018-10-31  Joseph Myers  <joseph@codesourcery.com>
 
        PR bootstrap/82856
index 2198649..00f7af4 100644 (file)
   }
 )
 
+;; It is tempting to want to use ST<OP> for relaxed and release
+;; memory models here.  However, that is incompatible with the
+;; C++ memory model for the following case:
+;;
+;;     atomic_fetch_add(ptr, 1, memory_order_relaxed);
+;;     atomic_thread_fence(memory_order_acquire);
+;;
+;; The problem is that the architecture says that ST<OP> (and LD<OP>
+;; insns where the destination is XZR) are not regarded as a read.
+;; However we also implement the acquire memory barrier with DMB LD,
+;; and so the ST<OP> is not blocked by the barrier.
+
 (define_insn "aarch64_atomic_<atomic_ldoptab><mode>_lse"
   [(set (match_operand:ALLI 0 "aarch64_sync_memory_operand" "+Q")
        (unspec_volatile:ALLI
           (match_operand:ALLI 1 "register_operand" "r")
           (match_operand:SI 2 "const_int_operand")]
       ATOMIC_LDOP))
-   (clobber (match_scratch:ALLI 3 "=&r"))]
+   (clobber (match_scratch:ALLI 3 "=r"))]
   "TARGET_LSE"
   {
    enum memmodel model = memmodel_from_int (INTVAL (operands[2]));