Commit fe1b6f0d by Bill Schmidt Committed by William Schmidt

rs6000.md (*call_indirect_nonlocal_sysv<mode>): Generate different code for…

rs6000.md (*call_indirect_nonlocal_sysv<mode>): Generate different code for -mno-speculate-indirect-jumps.

[gcc]

2018-01-17  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-17  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.

From-SVN: r256831
parent e91478f6
2018-01-17 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.
2018-01-17 Michael Meissner <meissner@linux.vnet.ibm.com> 2018-01-17 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (rs6000_emit_move): If we load or store a * config/rs6000/rs6000.c (rs6000_emit_move): If we load or store a
......
...@@ -10453,10 +10453,35 @@ ...@@ -10453,10 +10453,35 @@
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands); 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 "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>" (define_insn_and_split "*call_nonlocal_sysv<mode>"
[(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
...@@ -10541,10 +10566,35 @@ ...@@ -10541,10 +10566,35 @@
else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands); 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 "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>" (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
...@@ -10669,11 +10719,22 @@ ...@@ -10669,11 +10719,22 @@
(use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) (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)) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
(clobber (reg:P LR_REGNO))] (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)" "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
[(set_attr "type" "jmpreg") [(set_attr "type" "jmpreg")
(set_attr "length" "12")]) (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>" (define_insn "*call_value_indirect_aix<mode>"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
...@@ -10681,11 +10742,23 @@ ...@@ -10681,11 +10742,23 @@
(use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) (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)) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
(clobber (reg:P LR_REGNO))] (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)" "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
[(set_attr "type" "jmpreg") [(set_attr "type" "jmpreg")
(set_attr "length" "12")]) (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. ;; Call to indirect functions with the ELFv2 ABI.
;; Operand0 is the addresss of the function to call ;; Operand0 is the addresss of the function to call
;; Operand2 is the offset of the stack location holding the current TOC pointer ;; Operand2 is the offset of the stack location holding the current TOC pointer
...@@ -10909,7 +10982,13 @@ ...@@ -10909,7 +10982,13 @@
output_asm_insn (\"creqv 6,6,6\", operands); output_asm_insn (\"creqv 6,6,6\", operands);
if (which_alternative >= 2) 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) else if (DEFAULT_ABI == ABI_V4 && flag_pic)
{ {
gcc_assert (!TARGET_SECURE_PLT); gcc_assert (!TARGET_SECURE_PLT);
...@@ -10919,7 +10998,28 @@ ...@@ -10919,7 +10998,28 @@
return \"b %z0\"; return \"b %z0\";
}" }"
[(set_attr "type" "branch") [(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>" (define_insn "*sibcall_value_nonlocal_sysv<mode>"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
...@@ -10939,7 +11039,13 @@ ...@@ -10939,7 +11039,13 @@
output_asm_insn (\"creqv 6,6,6\", operands); output_asm_insn (\"creqv 6,6,6\", operands);
if (which_alternative >= 2) 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) else if (DEFAULT_ABI == ABI_V4 && flag_pic)
{ {
gcc_assert (!TARGET_SECURE_PLT); gcc_assert (!TARGET_SECURE_PLT);
...@@ -10949,7 +11055,28 @@ ...@@ -10949,7 +11055,28 @@
return \"b %z1\"; return \"b %z1\";
}" }"
[(set_attr "type" "branch") [(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. ;; AIX ABI sibling call patterns.
......
2018-01-17 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.
2018-01-17 Harald Anlauf <anlauf@gmx.de> 2018-01-17 Harald Anlauf <anlauf@gmx.de>
PR fortran/83874 PR fortran/83874
* gfortran.dg/pr83874.f90: New test. * gfortran.dg/pr83874.f90: New test.
......
/* { dg-do compile { target { powerpc64le-*-* } } } */ /* { dg-do compile { target { lp64 } } } */
/* { dg-additional-options "-mno-speculate-indirect-jumps" } */ /* { 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)(); extern int (*f)();
......
/* { 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-" } } */
/* { 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 ." } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment