From 6e1eaca96f745be9d40672c29cd2355c8b17b674 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Tue, 31 Jul 2018 17:36:09 +0000 Subject: [PATCH] AArch64 - disable CB[N]Z TB[N]Z when tracking speculation 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 (cb1): Disable when aarch64_track_speculation is true. (tb1): 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 | 10 ++++++++++ gcc/config/aarch64/aarch64.c | 33 ++++++++++++++++++++++++++++++--- gcc/config/aarch64/aarch64.md | 6 +++--- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d547126badf..b4340cc1c19 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2018-07-31 Richard Earnshaw + + * config/aarch64/aarch64.md (cb1): Disable when + aarch64_track_speculation is true. + (tb1): 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 * config/aarch64/aarch64.opt (mtrack-speculation): New target option. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index fa01475aa9e..bcbd8eb8458 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -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)); diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index de5230682d0..8984bbfa19e 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -690,7 +690,7 @@ (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", "\\t%0, "); @@ -720,7 +720,7 @@ (label_ref (match_operand 2 "" "")) (pc))) (clobber (reg:CC CC_REGNUM))] - "" + "!aarch64_track_speculation" { if (get_attr_length (insn) == 8) { @@ -756,7 +756,7 @@ (label_ref (match_operand 1 "" "")) (pc))) (clobber (reg:CC CC_REGNUM))] - "" + "!aarch64_track_speculation" { if (get_attr_length (insn) == 8) { -- 2.30.2