On Jan 19, 2018, at 12:32 PM, David Edelsohn <dje....@gmail.com> wrote:
> 
> 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, patch in progress.

FYI, I missed the 7.3 RC deadline, so this will only get picked up on a respin
anyway.  So I should have the fix in place before that happens.

Bill
> 
> Thanks, David
> 
> On Tue, Jan 16, 2018 at 9:08 PM, Bill Schmidt
> <wschm...@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  <wschm...@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  <wschm...@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 ." } } */
>> 
> 

Reply via email to