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 ." } } */ >> >