i386: Don't insert ENDBR at function entrance when called directly
authorH.J. Lu <hongjiu.lu@intel.com>
Tue, 24 Oct 2017 10:52:50 +0000 (10:52 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Tue, 24 Oct 2017 10:52:50 +0000 (03:52 -0700)
There is no need to insert ENDBR instruction at function entrance if
function is only called directly.

gcc/

PR target/82659
* config/i386/i386.c (rest_of_insert_endbranch): Don't insert
ENDBR instruction at function entrance if function is only
called directly.

gcc/testsuite/

PR target/82659
* gcc.target/i386/cet-label-2.c: New test.
* gcc.target/i386/cet-sjlj-4.c: Likewise.
* gcc.target/i386/cet-sjlj-5.c: Likewise.
* gcc.target/i386/cet-switch-3.c: Likewise.
* gcc.target/i386/pr82659-1.c: Likewise.
* gcc.target/i386/pr82659-2.c: Likewise.
* gcc.target/i386/pr82659-3.c: Likewise.
* gcc.target/i386/pr82659-4.c: Likewise.
* gcc.target/i386/pr82659-5.c: Likewise.
* gcc.target/i386/pr82659-6.c: Likewise.

From-SVN: r254040

13 files changed:
gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/cet-label-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cet-sjlj-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cet-sjlj-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cet-switch-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr82659-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr82659-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr82659-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr82659-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr82659-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr82659-6.c [new file with mode: 0644]

index c2c3a523405a918689bf79cc2b71582efcd0af4f..5a43ff890be9a45264c2626b86c6d0d525101e5e 100644 (file)
@@ -1,3 +1,10 @@
+2017-10-24  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/82659
+       * config/i386/i386.c (rest_of_insert_endbranch): Don't insert
+       ENDBR instruction at function entrance if function is only
+       called directly.
+
 2017-10-24  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/82628
index d8241fa15cd10be33d530f1fbd49a6ae84335952..d2188ad6086a0595025b42ebe524a3d314b8379e 100644 (file)
@@ -2587,7 +2587,8 @@ rest_of_insert_endbranch (void)
      nocf_check attribute.  This will allow to reduce the number of EB.  */
 
   if (!lookup_attribute ("nocf_check",
-                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))
+                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
+      && !cgraph_node::get (cfun->decl)->only_called_directly_p ())
     {
       cet_eb = gen_nop_endbr ();
 
index f188d8181e56217684e182ac1b23cccc9cdeab70..35c31e70b617da5181f08dbda57ddf8fc94c6b3c 100644 (file)
@@ -1,3 +1,17 @@
+2017-10-24  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/82659
+       * gcc.target/i386/cet-label-2.c: New test.
+       * gcc.target/i386/cet-sjlj-4.c: Likewise.
+       * gcc.target/i386/cet-sjlj-5.c: Likewise.
+       * gcc.target/i386/cet-switch-3.c: Likewise.
+       * gcc.target/i386/pr82659-1.c: Likewise.
+       * gcc.target/i386/pr82659-2.c: Likewise.
+       * gcc.target/i386/pr82659-3.c: Likewise.
+       * gcc.target/i386/pr82659-4.c: Likewise.
+       * gcc.target/i386/pr82659-5.c: Likewise.
+       * gcc.target/i386/pr82659-6.c: Likewise.
+
 2017-10-23  Sandra Loosemore  <sandra@codesourcery.com>
 
        * gcc.target/nios2/cdx-branch.c:  Fix broken test.
diff --git a/gcc/testsuite/gcc.target/i386/cet-label-2.c b/gcc/testsuite/gcc.target/i386/cet-label-2.c
new file mode 100644 (file)
index 0000000..c7f7981
--- /dev/null
@@ -0,0 +1,24 @@
+/* Verify that CET works.  */
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times "endbr32" 3 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 3 { target { ! ia32 } } } } */
+
+__attribute__ ((noinline, noclone))
+static int
+func (int arg)
+{
+  static void *array[] = { &&foo, &&bar };
+
+  goto *array[arg];
+foo:
+  return arg*111;
+bar:
+  return arg*777;
+}
+
+int
+foo (int arg)
+{
+  return func (arg);
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-4.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-4.c
new file mode 100644 (file)
index 0000000..d41406f
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times "endbr32" 3 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 3 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "rdssp\[dq]" 2 } } */
+/* { dg-final { scan-assembler-times "incssp\[dq]" 1 } } */
+
+/* Based on gcc.dg/setjmp-3.c.  */
+
+void *buf[5];
+
+extern void abort (void);
+
+void
+raise0 (void)
+{
+  __builtin_longjmp (buf, 1);
+}
+
+__attribute__ ((noinline, noclone))
+static int
+execute (int cmd)
+{
+  int last = 0;
+
+  if (__builtin_setjmp (buf) == 0)
+    while (1)
+      {
+       last = 1;
+       raise0 ();
+      }
+
+  if (last == 0)
+    return 0;
+  else
+    return cmd;
+}
+
+int main(void)
+{
+  if (execute (1) == 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-5.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-5.c
new file mode 100644 (file)
index 0000000..12ea9f4
--- /dev/null
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "call     _setjmp" 1 } } */
+/* { dg-final { scan-assembler-times "call     longjmp" 1 } } */
+
+#include <stdio.h>
+#include <setjmp.h>
+
+jmp_buf buf;
+static int bar (int);
+
+__attribute__ ((noinline, noclone))
+static int
+foo (int i)
+{
+  int j = i * 11;
+
+  if (!setjmp (buf))
+    {
+      j += 33;
+      printf ("After setjmp: j = %d\n", j);
+      bar (j);
+    }
+
+  return j + i;
+}
+
+__attribute__ ((noinline, noclone))
+static int
+bar (int i)
+{
+ int j = i;
+
+  j -= 111;
+  printf ("In longjmp: j = %d\n", j);
+  longjmp (buf, 1);
+
+  return j;
+}
+
+int
+main ()
+{
+  foo (10);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-switch-3.c b/gcc/testsuite/gcc.target/i386/cet-switch-3.c
new file mode 100644 (file)
index 0000000..9b1b436
--- /dev/null
@@ -0,0 +1,34 @@
+/* Verify that CET works.  */
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection -mcet -mcet-switch" } */
+/* { dg-final { scan-assembler-times "endbr32" 12 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 12 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "\[ \t]+jmp\[ \t]+\[*]" 1 } } */
+
+void func2 (int);
+
+__attribute__ ((noinline, noclone))
+static int
+func1 (int arg)
+{
+  switch (arg)
+  {
+    case 1: func2 (arg*100);
+    case 2: func2 (arg*300);
+    case 5: func2 (arg*500);
+    case 8: func2 (arg*700);
+    case 7: func2 (arg*900);
+    case -1: func2 (arg*-100);
+    case -2: func2 (arg*-300);
+    case -5: func2 (arg*-500);
+    case -7: func2 (arg*-700);
+    case -9: func2 (arg*-900);
+  }
+  return 0;
+}
+
+int
+foo (int arg)
+{
+  return func1 (arg);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82659-1.c b/gcc/testsuite/gcc.target/i386/pr82659-1.c
new file mode 100644 (file)
index 0000000..485771d
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times {\mendbr} 1 } } */
+
+extern int x;
+
+static void
+__attribute__ ((noinline, noclone))
+test (int i)
+{
+  x = i;
+}
+
+void
+bar (int i)
+{
+  test (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82659-2.c b/gcc/testsuite/gcc.target/i386/pr82659-2.c
new file mode 100644 (file)
index 0000000..7afffa4
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times {\mendbr} 2 } } */
+
+extern int x;
+
+void
+test (int i)
+{
+  x = i;
+}
+
+void
+bar (int i)
+{
+  test (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82659-3.c b/gcc/testsuite/gcc.target/i386/pr82659-3.c
new file mode 100644 (file)
index 0000000..5f97b31
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times {\mendbr} 2 } } */
+
+extern int x;
+
+static void
+__attribute__ ((noinline, noclone))
+test (int i)
+{
+  x = i;
+}
+
+extern __typeof (test) foo __attribute__ ((alias ("test")));
+
+void
+bar (int i)
+{
+  test (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82659-4.c b/gcc/testsuite/gcc.target/i386/pr82659-4.c
new file mode 100644 (file)
index 0000000..c3cacac
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times {\mendbr} 2 } } */
+
+static void
+test (void)
+{
+}
+
+void *
+bar (void)
+{
+  return test;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82659-5.c b/gcc/testsuite/gcc.target/i386/pr82659-5.c
new file mode 100644 (file)
index 0000000..9541367
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times {\mendbr} 1 } } */
+
+static void
+test (void)
+{
+}
+
+void (*test_p) (void) = test;
diff --git a/gcc/testsuite/gcc.target/i386/pr82659-6.c b/gcc/testsuite/gcc.target/i386/pr82659-6.c
new file mode 100644 (file)
index 0000000..51fc1a9
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mcet" } */
+/* { dg-final { scan-assembler-times {\mendbr} 2 } } */
+
+extern int x;
+
+ __attribute__ ((visibility ("hidden")))
+void
+test (int i)
+{
+  x = i;
+}
+
+void
+bar (int i)
+{
+  test (i);
+}