This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] i386: Don't generate ENDBR if function is only called directly


On Tue, Oct 24, 2017 at 2:33 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Tue, Oct 24, 2017 at 10:39 AM, Tsimbalist, Igor V
> <igor.v.tsimbalist@intel.com> wrote:
>> OK.
>
> +/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
> +/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */
>
> I think we can only check for {\mendbr} in the testcases. There are
> already plenty of testcases that check for the correct instruction.
>
> Otherwise, LGTM
>

This is what I checked in.

Thanks.

-- 
H.J.
From 81893b3645f6f0771771690e58629d3d233fcdb2 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 22 Oct 2017 06:09:27 -0700
Subject: [PATCH] i386: Don't insert ENDBR at function entrance when called
 directly

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.
---
 gcc/config/i386/i386.c                       |  3 +-
 gcc/testsuite/gcc.target/i386/cet-label-2.c  | 24 ++++++++++++++
 gcc/testsuite/gcc.target/i386/cet-sjlj-4.c   | 45 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/cet-sjlj-5.c   | 48 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/cet-switch-3.c | 34 ++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr82659-1.c    | 18 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82659-2.c    | 17 ++++++++++
 gcc/testsuite/gcc.target/i386/pr82659-3.c    | 20 ++++++++++++
 gcc/testsuite/gcc.target/i386/pr82659-4.c    | 14 ++++++++
 gcc/testsuite/gcc.target/i386/pr82659-5.c    | 10 ++++++
 gcc/testsuite/gcc.target/i386/pr82659-6.c    | 18 +++++++++++
 11 files changed, 250 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-switch-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82659-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82659-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82659-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82659-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82659-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82659-6.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 72caf62bbf8..c75c8ef95e5 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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 ();
 
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
index 00000000000..c7f79819079
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-label-2.c
@@ -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
index 00000000000..d41406fde1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-4.c
@@ -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
index 00000000000..12ea9f4e442
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-5.c
@@ -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
index 00000000000..9b1b4369582
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-switch-3.c
@@ -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
index 00000000000..485771d0f38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82659-1.c
@@ -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
index 00000000000..7afffa440aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82659-2.c
@@ -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
index 00000000000..5f97b314092
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82659-3.c
@@ -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
index 00000000000..c3cacaccbef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82659-4.c
@@ -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
index 00000000000..95413671d5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82659-5.c
@@ -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
index 00000000000..51fc1a9f5c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82659-6.c
@@ -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);
+}
-- 
2.13.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]