rs6000.md (*call_indirect_nonlocal_sysv<mode>): Generate different code for -mno...
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Thu, 18 Jan 2018 01:21:50 +0000 (01:21 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Thu, 18 Jan 2018 01:21:50 +0000 (01:21 +0000)
[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

gcc/ChangeLog
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-1.c
gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c [new file with mode: 0644]

index e01194c..5e4d6b3 100644 (file)
@@ -1,3 +1,18 @@
+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>
 
        * config/rs6000/rs6000.c (rs6000_emit_move): If we load or store a
index fe02734..4cef5bb 100644 (file)
   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"))
   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 "" "")
    (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"))
    (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
     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);
     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 "" "")
     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);
     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 346cdc0..f710c15 100644 (file)
@@ -1,5 +1,12 @@
+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>
-                         
+
        PR fortran/83874
        * gfortran.dg/pr83874.f90: New test.
 
index 1a0cc88..d66e9c3 100644 (file)
@@ -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)();
 
diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-7.c
new file mode 100644 (file)
index 0000000..d19245e
--- /dev/null
@@ -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-" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-8.c
new file mode 100644 (file)
index 0000000..be2150e
--- /dev/null
@@ -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 ." } } */