AArch64 - disable CB[N]Z TB[N]Z when tracking speculation
authorRichard Earnshaw <rearnsha@arm.com>
Tue, 31 Jul 2018 17:36:09 +0000 (17:36 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Tue, 31 Jul 2018 17:36:09 +0000 (17:36 +0000)
The CB[N]Z and TB[N]Z instructions do not expose the comparison through
the condition code flags.  This makes it impossible to track speculative
execution through such a branch.  We can handle this relatively easily
by simply disabling the patterns in this case.

A side effect of this is that the split patterns for the atomic operations
need to also avoid generating these instructions.  They mostly have simple
fall-backs for this already.

* config/aarch64/aarch64.md (cb<optab><mode>1): Disable when
aarch64_track_speculation is true.
(tb<optab><mode>1): Likewise.
* config/aarch64/aarch64.c (aarch64_split_compare_regs): Do not
generate CB[N]Z when tracking speculation.
(aarch64_split_compare_and_swap): Likewise.
(aarch64_split_atomic_op): Likewise.

From-SVN: r263172

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md

index d547126badf947e81dbb289e50dde7ed8ddd2819..b4340cc1c194e00609ca45daae63a11ac96c47d4 100644 (file)
@@ -1,3 +1,13 @@
+2018-07-31  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/aarch64/aarch64.md (cb<optab><mode>1): Disable when
+       aarch64_track_speculation is true.
+       (tb<optab><mode>1): Likewise.
+       * config/aarch64/aarch64.c (aarch64_split_compare_regs): Do not
+       generate CB[N]Z when tracking speculation.
+       (aarch64_split_compare_and_swap): Likewise.
+       (aarch64_split_atomic_op): Likewise.
+
 2018-07-31  Richard Earnshaw  <rearnsha@arm.com>
 
        * config/aarch64/aarch64.opt (mtrack-speculation): New target option.
index fa01475aa9ee579b6a3b2526295b622157120660..bcbd8eb84586fd98a2f9fc1a33904238c058cc96 100644 (file)
@@ -14494,7 +14494,16 @@ aarch64_split_compare_and_swap (rtx operands[])
 
   if (strong_zero_p)
     {
-      x = gen_rtx_NE (VOIDmode, rval, const0_rtx);
+      if (aarch64_track_speculation)
+       {
+         /* Emit an explicit compare instruction, so that we can correctly
+            track the condition codes.  */
+         rtx cc_reg = aarch64_gen_compare_reg (NE, rval, const0_rtx);
+         x = gen_rtx_NE (GET_MODE (cc_reg), cc_reg, const0_rtx);
+       }
+      else
+       x = gen_rtx_NE (VOIDmode, rval, const0_rtx);
+
       x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
                                gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
       aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
@@ -14512,7 +14521,16 @@ aarch64_split_compare_and_swap (rtx operands[])
 
   if (!is_weak)
     {
-      x = gen_rtx_NE (VOIDmode, scratch, const0_rtx);
+      if (aarch64_track_speculation)
+       {
+         /* Emit an explicit compare instruction, so that we can correctly
+            track the condition codes.  */
+         rtx cc_reg = aarch64_gen_compare_reg (NE, scratch, const0_rtx);
+         x = gen_rtx_NE (GET_MODE (cc_reg), cc_reg, const0_rtx);
+       }
+      else
+       x = gen_rtx_NE (VOIDmode, scratch, const0_rtx);
+
       x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
                                gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
       aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
@@ -14848,7 +14866,16 @@ aarch64_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
   aarch64_emit_store_exclusive (mode, cond, mem,
                                gen_lowpart (mode, new_out), model_rtx);
 
-  x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
+  if (aarch64_track_speculation)
+    {
+      /* Emit an explicit compare instruction, so that we can correctly
+        track the condition codes.  */
+      rtx cc_reg = aarch64_gen_compare_reg (NE, cond, const0_rtx);
+      x = gen_rtx_NE (GET_MODE (cc_reg), cc_reg, const0_rtx);
+    }
+  else
+    x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
+
   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
                            gen_rtx_LABEL_REF (Pmode, label), pc_rtx);
   aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
index de5230682d02f6ee68d7de841563f9f4bc7a3199..8984bbfa19e6472e3f9199b304690851158c5846 100644 (file)
                                (const_int 0))
                           (label_ref (match_operand 1 "" ""))
                           (pc)))]
-  ""
+  "!aarch64_track_speculation"
   {
     if (get_attr_length (insn) == 8)
       return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, ");
             (label_ref (match_operand 2 "" ""))
             (pc)))
    (clobber (reg:CC CC_REGNUM))]
-  ""
+  "!aarch64_track_speculation"
   {
     if (get_attr_length (insn) == 8)
       {
                           (label_ref (match_operand 1 "" ""))
                           (pc)))
    (clobber (reg:CC CC_REGNUM))]
-  ""
+  "!aarch64_track_speculation"
   {
     if (get_attr_length (insn) == 8)
       {