[PATCH v2, rs6000] Implement 32- and 64-bit BE handling for -mno-speculate-indirect-jumps

David Edelsohn dje.gcc@gmail.com
Fri Jan 19 20:02:00 GMT 2018


This patch is incorrect for AIX.  Which also means that the backport
to GCC 7 branch is incorrect for AIX and must be corrected before the
release.

AIX assembler does not accept "." (period) as the current address.

"b ." is incorrect.  And testing for "b ." is incorrect.  I am going
to try testing with "$" in trunk.

GCC 7.3 must be re-spun.

Thanks, David

On Tue, Jan 16, 2018 at 9:08 PM, Bill Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> Hi,
>
> This patch supercedes and extends https://gcc.gnu.org/ml/gcc-patches/2018-01/msg01479.html,
> adding the remaining big-endian support for -mno-speculate-indirect-jumps.
> This includes 32-bit support for indirect calls and sibling calls, and
> 64-bit support for indirect calls.  The endian-neutral switch handling has
> already been committed.
>
> Using -m32 -O2 on safe-indirect-jumps-1.c results in a test for a sibling
> call, so this has been added as safe-indirect-jumps-8.c.  Also,
> safe-indirect-jumps-7.c adds a variant that will not generate a sibling
> call for -m32, so we still get indirect call coverage.
>
> Bootstrapped and tested on powerpc64-linux-gnu and powerpc64le-linux-gnu
> with no regressions.  Is this okay for trunk?
>
> Thanks,
> Bill
>
>
> [gcc]
>
> 2018-01-16  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>
>         * config/rs6000/rs6000.md (*call_indirect_nonlocal_sysv<mode>):
>         Generate different code for -mno-speculate-indirect-jumps.
>         (*call_value_indirect_nonlocal_sysv<mode>): Likewise.
>         (*call_indirect_aix<mode>): Disable for
>         -mno-speculate-indirect-jumps.
>         (*call_indirect_aix<mode>_nospec): New define_insn.
>         (*call_value_indirect_aix<mode>): Disable for
>         -mno-speculate-indirect-jumps.
>         (*call_value_indirect_aix<mode>_nospec): New define_insn.
>         (*sibcall_nonlocal_sysv<mode>): Generate different code for
>         -mno-speculate-indirect-jumps.
>         (*sibcall_value_nonlocal_sysv<mode>): Likewise.
>
> [gcc/testsuite]
>
> 2018-01-16  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>
>         * gcc.target/powerpc/safe-indirect-jump-1.c: Remove endian
>         restriction, but still restrict to 64-bit.
>         * gcc.target/powerpc/safe-indirect-jump-7.c: New file.
>         * gcc.target/powerpc/safe-indirect-jump-8.c: New file.
>
>
> Index: gcc/config/rs6000/rs6000.md
> ===================================================================
> --- gcc/config/rs6000/rs6000.md (revision 256753)
> +++ gcc/config/rs6000/rs6000.md (working copy)
> @@ -10453,10 +10453,35 @@
>    else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
>      output_asm_insn ("creqv 6,6,6", operands);
>
> -  return "b%T0l";
> +  if (rs6000_speculate_indirect_jumps
> +      || which_alternative == 1 || which_alternative == 3)
> +    return "b%T0l";
> +  else
> +    return "crset eq\;beq%T0l-";
>  }
>    [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
> -   (set_attr "length" "4,4,8,8")])
> +   (set (attr "length")
> +       (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "4")
> +              (and (eq (symbol_ref "which_alternative") (const_int 0))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "8")
> +              (eq (symbol_ref "which_alternative") (const_int 1))
> +                 (const_string "4")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "8")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "12")
> +              (eq (symbol_ref "which_alternative") (const_int 3))
> +                 (const_string "8")]
> +             (const_string "4")))])
>
>  (define_insn_and_split "*call_nonlocal_sysv<mode>"
>    [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
> @@ -10541,10 +10566,35 @@
>    else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
>      output_asm_insn ("creqv 6,6,6", operands);
>
> -  return "b%T1l";
> +  if (rs6000_speculate_indirect_jumps
> +      || which_alternative == 1 || which_alternative == 3)
> +    return "b%T1l";
> +  else
> +    return "crset eq\;beq%T1l-";
>  }
>    [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
> -   (set_attr "length" "4,4,8,8")])
> +   (set (attr "length")
> +       (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "4")
> +              (and (eq (symbol_ref "which_alternative") (const_int 0))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "8")
> +              (eq (symbol_ref "which_alternative") (const_int 1))
> +                 (const_string "4")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "8")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "12")
> +              (eq (symbol_ref "which_alternative") (const_int 3))
> +                 (const_string "8")]
> +             (const_string "4")))])
>
>  (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
>    [(set (match_operand 0 "" "")
> @@ -10669,11 +10719,22 @@
>     (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
>     (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
>     (clobber (reg:P LR_REGNO))]
> -  "DEFAULT_ABI == ABI_AIX"
> +  "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
>    "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
>    [(set_attr "type" "jmpreg")
>     (set_attr "length" "12")])
>
> +(define_insn "*call_indirect_aix<mode>_nospec"
> +  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
> +        (match_operand 1 "" "g,g"))
> +   (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
> +   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
> +   (clobber (reg:P LR_REGNO))]
> +  "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
> +  "crset eq\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
> +  [(set_attr "type" "jmpreg")
> +   (set_attr "length" "16")])
> +
>  (define_insn "*call_value_indirect_aix<mode>"
>    [(set (match_operand 0 "" "")
>         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
> @@ -10681,11 +10742,23 @@
>     (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
>     (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
>     (clobber (reg:P LR_REGNO))]
> -  "DEFAULT_ABI == ABI_AIX"
> +  "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
>    "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
>    [(set_attr "type" "jmpreg")
>     (set_attr "length" "12")])
>
> +(define_insn "*call_value_indirect_aix<mode>_nospec"
> +  [(set (match_operand 0 "" "")
> +       (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
> +             (match_operand 2 "" "g,g")))
> +   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
> +   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
> +   (clobber (reg:P LR_REGNO))]
> +  "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
> +  "crset eq\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
> +  [(set_attr "type" "jmpreg")
> +   (set_attr "length" "16")])
> +
>  ;; Call to indirect functions with the ELFv2 ABI.
>  ;; Operand0 is the addresss of the function to call
>  ;; Operand2 is the offset of the stack location holding the current TOC pointer
> @@ -10909,7 +10982,13 @@
>      output_asm_insn (\"creqv 6,6,6\", operands);
>
>    if (which_alternative >= 2)
> -    return \"b%T0\";
> +    {
> +      if (rs6000_speculate_indirect_jumps)
> +       return \"b%T0\";
> +      else
> +       /* Can use CR0 since it is volatile across sibcalls.  */
> +       return \"crset eq\;beq%T0-\;b .\";
> +    }
>    else if (DEFAULT_ABI == ABI_V4 && flag_pic)
>      {
>        gcc_assert (!TARGET_SECURE_PLT);
> @@ -10919,7 +10998,28 @@
>      return \"b %z0\";
>  }"
>    [(set_attr "type" "branch")
> -   (set_attr "length" "4,8,4,8")])
> +   (set (attr "length")
> +       (cond [(eq (symbol_ref "which_alternative") (const_int 0))
> +                 (const_string "4")
> +              (eq (symbol_ref "which_alternative") (const_int 1))
> +                 (const_string "8")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "4")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "12")
> +              (and (eq (symbol_ref "which_alternative") (const_int 3))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "8")
> +              (and (eq (symbol_ref "which_alternative") (const_int 3))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "16")]
> +             (const_string "4")))])
>
>  (define_insn "*sibcall_value_nonlocal_sysv<mode>"
>    [(set (match_operand 0 "" "")
> @@ -10939,7 +11039,13 @@
>      output_asm_insn (\"creqv 6,6,6\", operands);
>
>    if (which_alternative >= 2)
> -    return \"b%T1\";
> +    {
> +      if (rs6000_speculate_indirect_jumps)
> +       return \"b%T1\";
> +      else
> +       /* Can use CR0 since it is volatile across sibcalls.  */
> +       return \"crset eq\;beq%T1-\;b .\";
> +    }
>    else if (DEFAULT_ABI == ABI_V4 && flag_pic)
>      {
>        gcc_assert (!TARGET_SECURE_PLT);
> @@ -10949,7 +11055,28 @@
>      return \"b %z1\";
>  }"
>    [(set_attr "type" "branch")
> -   (set_attr "length" "4,8,4,8")])
> +   (set (attr "length")
> +       (cond [(eq (symbol_ref "which_alternative") (const_int 0))
> +                 (const_string "4")
> +              (eq (symbol_ref "which_alternative") (const_int 1))
> +                 (const_string "8")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "4")
> +              (and (eq (symbol_ref "which_alternative") (const_int 2))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "12")
> +              (and (eq (symbol_ref "which_alternative") (const_int 3))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 1)))
> +                 (const_string "8")
> +              (and (eq (symbol_ref "which_alternative") (const_int 3))
> +                   (eq (symbol_ref "rs6000_speculate_indirect_jumps")
> +                       (const_int 0)))
> +                 (const_string "16")]
> +             (const_string "4")))])
>
>  ;; AIX ABI sibling call patterns.
>
> Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c
> ===================================================================
> --- gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c     (revision 256753)
> +++ gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c     (working copy)
> @@ -1,7 +1,7 @@
> -/* { dg-do compile { target { powerpc64le-*-* } } } */
> +/* { dg-do compile { target { lp64 } } } */
>  /* { dg-additional-options "-mno-speculate-indirect-jumps" } */
>
> -/* Test for deliberate misprediction of indirect calls for ELFv2.  */
> +/* Test for deliberate misprediction of indirect calls.  */
>
>  extern int (*f)();
>
> Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c
> ===================================================================
> --- gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c     (nonexistent)
> +++ gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c     (working copy)
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-mno-speculate-indirect-jumps" } */
> +
> +/* Test for deliberate misprediction of indirect calls.  */
> +
> +extern int (*f)();
> +
> +int bar ()
> +{
> +  return (*f) () * 53;
> +}
> +
> +/* { dg-final { scan-assembler "crset eq" } } */
> +/* { dg-final { scan-assembler "beqctrl-" } } */
> Index: gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c
> ===================================================================
> --- gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c     (nonexistent)
> +++ gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c     (working copy)
> @@ -0,0 +1,15 @@
> +/* { dg-do compile { target { ilp32 } } } */
> +/* { dg-additional-options "-O2 -mno-speculate-indirect-jumps" } */
> +
> +/* Test for deliberate misprediction of -m32 sibcalls.  */
> +
> +extern int (*f)();
> +
> +int bar ()
> +{
> +  return (*f) ();
> +}
> +
> +/* { dg-final { scan-assembler "crset eq" } } */
> +/* { dg-final { scan-assembler "beqctr-" } } */
> +/* { dg-final { scan-assembler "b ." } } */
>



More information about the Gcc-patches mailing list