aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite
diff options
context:
space:
mode:
authorCaroline Tice <cmtice@google.com>2018-01-08 18:25:12 (GMT)
committerCaroline Tice <cmtice@google.com>2018-01-08 18:25:12 (GMT)
commitdeec799746e92ab0487eca489499ade08a2610bf (patch)
tree9a2c42ca86130fa98e61c5d7bfb7e890f501a066 /gcc-4.9/gcc/testsuite
parentdca601e5d2b032ac5cca1df90ac56077ccf5d665 (diff)
downloadtoolchain_gcc-deec799746e92ab0487eca489499ade08a2610bf.zip
toolchain_gcc-deec799746e92ab0487eca489499ade08a2610bf.tar.gz
toolchain_gcc-deec799746e92ab0487eca489499ade08a2610bf.tar.bz2
[GCC] Commit retpoline patch code, for fixing security issues.
This applies the Intel GCC code patches, to allow compiling with appropriate flags for mitigating the indirect branch variant of the speculative execution security flaw. Bug: None Test: This is already in place in ChromeOS and has been tested on the ChromeOS kernels. Change-Id: Ideffb433b697f1fe7e4ca2c1eaa968160abfcc8b
Diffstat (limited to 'gcc-4.9/gcc/testsuite')
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c20
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c20
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c42
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c22
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c20
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c20
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c22
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c43
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c40
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c20
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c20
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c42
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c18
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c18
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c41
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-1.c23
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-2.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-3.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-4.c22
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-5.c22
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-6.c15
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-7.c15
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-8.c29
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-no-patching.c27
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-patching.c20
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-sibling-call.c26
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c12
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c22
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c22
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c18
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c12
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c12
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c12
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c14
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c13
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c13
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c14
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c23
55 files changed, 930 insertions, 241 deletions
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
new file mode 100644
index 0000000..46ae832
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
new file mode 100644
index 0000000..7c81008
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+ /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
new file mode 100644
index 0000000..46685d9
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
new file mode 100644
index 0000000..8f70177
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
new file mode 100644
index 0000000..008ccac
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+
+void func0 (void);
+void func1 (void);
+void func2 (void);
+void func3 (void);
+void func4 (void);
+void func5 (void);
+
+void
+bar (int i)
+{
+ switch (i)
+ {
+ default:
+ func0 ();
+ break;
+ case 1:
+ func1 ();
+ break;
+ case 2:
+ func2 ();
+ break;
+ case 3:
+ func3 ();
+ break;
+ case 4:
+ func4 ();
+ break;
+ case 5:
+ func5 ();
+ break;
+ }
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
new file mode 100644
index 0000000..88c87c1
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+extern void male_indirect_jump (long)
+ __attribute__ ((indirect_branch("thunk")));
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
new file mode 100644
index 0000000..80f3705
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+__attribute__ ((indirect_branch("thunk")))
+void
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
new file mode 100644
index 0000000..7f56725
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+extern int male_indirect_jump (long)
+ __attribute__ ((indirect_branch("thunk-inline")));
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
new file mode 100644
index 0000000..fd4ab1d
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+__attribute__ ((indirect_branch("thunk-inline")))
+int
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
new file mode 100644
index 0000000..1ffbf3b
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+extern int male_indirect_jump (long)
+ __attribute__ ((indirect_branch("thunk-extern")));
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
new file mode 100644
index 0000000..1559072
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+__attribute__ ((indirect_branch("thunk-extern")))
+int
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
new file mode 100644
index 0000000..58347f3
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+
+void func0 (void);
+void func1 (void);
+void func2 (void);
+void func3 (void);
+void func4 (void);
+void func5 (void);
+
+__attribute__ ((indirect_branch("thunk-extern")))
+void
+bar (int i)
+{
+ switch (i)
+ {
+ default:
+ func0 ();
+ break;
+ case 1:
+ func1 ();
+ break;
+ case 2:
+ func2 ();
+ break;
+ case 3:
+ func3 ();
+ break;
+ case 4:
+ func4 ();
+ break;
+ case 5:
+ func5 ();
+ break;
+ }
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
new file mode 100644
index 0000000..3a7cbf0
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+
+void func0 (void);
+void func1 (void);
+void func2 (void);
+void func3 (void);
+void func4 (void);
+void func5 (void);
+
+__attribute__ ((indirect_branch("keep")))
+void
+bar (int i)
+{
+ switch (i)
+ {
+ default:
+ func0 ();
+ break;
+ case 1:
+ func1 ();
+ break;
+ case 2:
+ func2 ();
+ break;
+ case 3:
+ func3 ();
+ break;
+ case 4:
+ func4 ();
+ break;
+ case 5:
+ func5 ();
+ break;
+ }
+}
+
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
new file mode 100644
index 0000000..03a4bd0
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
new file mode 100644
index 0000000..216b60a
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+ /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
new file mode 100644
index 0000000..1537239
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
new file mode 100644
index 0000000..c82e530
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
new file mode 100644
index 0000000..a2614e5
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+
+void func0 (void);
+void func1 (void);
+void func2 (void);
+void func3 (void);
+void func4 (void);
+void func5 (void);
+
+void
+bar (int i)
+{
+ switch (i)
+ {
+ default:
+ func0 ();
+ break;
+ case 1:
+ func1 ();
+ break;
+ case 2:
+ func2 ();
+ break;
+ case 3:
+ func3 ();
+ break;
+ case 4:
+ func4 ();
+ break;
+ case 5:
+ func5 ();
+ break;
+ }
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
new file mode 100644
index 0000000..58f2de9
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
new file mode 100644
index 0000000..cfccefd
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
new file mode 100644
index 0000000..6fe5ce7
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
new file mode 100644
index 0000000..65cd997
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+int
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
new file mode 100644
index 0000000..3482bfe
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+
+void func0 (void);
+void func1 (void);
+void func2 (void);
+void func3 (void);
+void func4 (void);
+void func5 (void);
+
+void
+bar (int i)
+{
+ switch (i)
+ {
+ default:
+ func0 ();
+ break;
+ case 1:
+ func1 ();
+ break;
+ case 2:
+ func2 ();
+ break;
+ case 3:
+ func3 ();
+ break;
+ case 4:
+ func4 ();
+ break;
+ case 5:
+ func5 ();
+ break;
+ }
+}
+
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
new file mode 100644
index 0000000..fefeaec
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } *
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
new file mode 100644
index 0000000..8975cf3
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch[256];
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch[offset](offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tnop} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
new file mode 100644
index 0000000..d103c4d
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
new file mode 100644
index 0000000..4c75a0a
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
new file mode 100644
index 0000000..081f512
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-1.c
deleted file mode 100644
index aa1f424..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-1.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Verify -mpatch-functions-for-instrumentation works. */
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation" } */
-
-/* Check nop-bytes at beginning. */
-/* { dg-final { scan-assembler ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* Check nop-bytes at end. */
-/* { dg-final { scan-assembler "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-__attribute__ ((noinline))
-void foo()
-{
- /* Dummy loop. */
- int x = 0;
- while (++x);
-}
-
-int main()
-{
- foo();
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-2.c
deleted file mode 100644
index 78de867..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-2.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation -mno-patch-functions-main-always" } */
-
-/* Function is small to be instrumented with default values. Check there
- aren't any nop-bytes at beginning or end of function. */
-
-/* { dg-final { scan-assembler-not ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler-not "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-__attribute__ ((noinline))
-void foo()
-{
- int x = 0;
-}
-
-int main()
-{
- foo();
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-3.c
deleted file mode 100644
index 9e8eb52..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-3.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation --param function-patch-min-instructions=0" } */
-
-/* Function should have nop-bytes with -mpatch-function-min-instructions=0.
- Check there are nop-bytes at beginning and end of function. */
-
-/* { dg-final { scan-assembler ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-__attribute__ ((noinline))
-void foo()
-{
- int x = 0;
-}
-
-int main()
-{
- foo();
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-4.c
deleted file mode 100644
index 7a031d7..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-4.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation -mpatch-functions-ignore-loops -mno-patch-functions-main-always" } */
-
-/* Function is too small to be patched when ignoring the loop.
- Check there aren't any nop-bytes at beginning and end of function. */
-
-/* { dg-final { scan-assembler-not ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler-not "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-__attribute__ ((noinline))
-void foo()
-{
- int x = 0;
- while (++x);
-}
-
-int main()
-{
- foo();
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-5.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-5.c
deleted file mode 100644
index cd6a014..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-5.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation -mpatch-functions-ignore-loops --param function-patch-min-instructions=0" } */
-
-/* Function should be patched with nop bytes with given options.
- Check there are nop-bytes at beginning and end of function. */
-
-/* { dg-final { scan-assembler ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-__attribute__ ((noinline))
-void foo()
-{
- int x = 0;
- while (++x);
-}
-
-int main()
-{
- foo();
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-6.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-6.c
deleted file mode 100644
index c1d6446..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-6.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation" } */
-
-/* 'main' function should always be patched, irrespective of how small it is.
- Check there are nop-bytes at beginning and end of main. */
-
-/* { dg-final { scan-assembler ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-int main()
-{
- int x = 0;
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-7.c
deleted file mode 100644
index f625298..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-7.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation -mno-patch-functions-main-always" } */
-
-/* 'main' shouldn't be patched with the option -mno-patch-functions-main-always.
- Check there aren't any nop-bytes at beginning and end of main. */
-
-/* { dg-final { scan-assembler-not ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler-not "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-int main()
-{
- int x = 0;
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-8.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-8.c
deleted file mode 100644
index 436379c..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-8.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Verify -mpatch-functions-for-instrumentation works. */
-/* { dg-do run } */
-/* { dg-require-effective-target lp64 } */
-
-/* -O2 forces a sibling call for foo from bar. */
-/* { dg-options "-O2 -mpatch-functions-for-instrumentation --param function-patch-min-instructions=0" } */
-
-__attribute__ ((noinline))
-int foo()
-{
- /* Dummy loop. */
- int x = 10;
- int y = 100;
- while (--x)
- ++y;
- return y;
-}
-
-__attribute__ ((noinline))
-int bar()
-{
- return foo();
-}
-
-int main()
-{
- bar();
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-no-patching.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-no-patching.c
deleted file mode 100644
index cad6f2d..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-no-patching.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mpatch-functions-for-instrumentation -mno-patch-functions-main-always" } */
-
-/* Even complicated functions shouldn't get patched if they have the
- never_patch_for_instrumentation attribute. */
-
-/* { dg-final { scan-assembler-not ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler-not "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-__attribute__ ((never_patch_for_instrumentation))
-int foo () {
- volatile unsigned x = 0;
- volatile unsigned y = 1;
- x += y;
- x *= y;
- while (++x)
- foo ();
- return y;
-}
-
-
-int main ()
-{
- int x = 0;
- return 0;
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-patching.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-patching.c
deleted file mode 100644
index 86ad159..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-force-patching.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-O3 -mpatch-functions-for-instrumentation -mno-patch-functions-main-always" } */
-
-/* Functions which have the always_patch attribute should be patched no matter
- what. Check that there are nop-bytes at the beginning and end of the
- function. We add -O3 so that the compiler will try to inline foo (but it
- will be blocked by the attribute). */
-
-/* { dg-final { scan-assembler ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-/* { dg-final { scan-assembler "ret(.*).byte\t0x90(.*).byte\t0x90" } } */
-
-__attribute__ ((always_patch_for_instrumentation))
-static int foo () {
- return 3;
-}
-
-int main () {
- volatile int x = foo ();
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-sibling-call.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-sibling-call.c
deleted file mode 100644
index 847a95c..0000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/patch-functions-sibling-call.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* -O2 forces a sibling call. */
-/* { dg-options "-O2 -mpatch-functions-for-instrumentation" } */
-
-/* { dg-final { scan-assembler ".byte\t0xeb,0x09(.*).byte\t0x90" } } */
-
-/* Checks correct nop-bytes are generated just before a sibling call. */
-/* { dg-final { scan-assembler ".byte\t0xeb,0x09(.*).byte\t0x90(.*)jmp" } } */
-
-/* Not instrumented as function has no loop and is small. */
-__attribute__ ((noinline))
-int foo(int n)
-{
- int x = 0;
- return n + 10;
-}
-
-__attribute__ ((noinline))
-int bar(int n)
-{
- /* Dummy loop. */
- while (--n)
- n = n * 2;
- return foo(n);
-}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
new file mode 100644
index 0000000..406956f
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk" } */
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
new file mode 100644
index 0000000..aecea42
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */
+
+extern void (*bar) (void);
+
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
new file mode 100644
index 0000000..fee8609
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */
+
+extern void (*bar) (void);
+
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x3 } } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
new file mode 100644
index 0000000..851115a
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+
+extern void (*bar) (void);
+
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
new file mode 100644
index 0000000..7acb6fa
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+
+extern void (*bar) (void);
+extern int foo (void) __attribute__ ((function_return("thunk")));
+
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
new file mode 100644
index 0000000..bf340fa
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+
+extern void (*bar) (void);
+
+__attribute__ ((function_return("thunk-inline")))
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
new file mode 100644
index 0000000..735f864
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */
+
+extern void (*bar) (void);
+
+__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk")))
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
new file mode 100644
index 0000000..cf39205
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk-extern -fno-pic" } */
+
+extern void (*bar) (void);
+
+__attribute__ ((function_return("keep"), indirect_branch("keep")))
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
new file mode 100644
index 0000000..190947c
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk-inline" } */
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
new file mode 100644
index 0000000..d71de3a
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk-extern" } */
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
new file mode 100644
index 0000000..68c2212
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep" } */
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
new file mode 100644
index 0000000..28c576e
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep" } */
+
+extern void foo (void) __attribute__ ((function_return("thunk")));
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
new file mode 100644
index 0000000..10ad40b
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep" } */
+
+__attribute__ ((function_return("thunk-inline")))
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
new file mode 100644
index 0000000..7ac0bea
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=keep" } */
+
+__attribute__ ((function_return("thunk-extern")))
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
new file mode 100644
index 0000000..777ab7c
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk-inline" } */
+
+extern void foo (void) __attribute__ ((function_return("keep")));
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
new file mode 100644
index 0000000..0b285ca
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic"} */
+
+extern void (*bar) (void);
+
+int
+foo (void)
+{
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */
+/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */