aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/gcc.target
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/testsuite/gcc.target')
-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 000000000..46ae8329b
--- /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 000000000..7c8100822
--- /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 000000000..46685d9a6
--- /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 000000000..8f701775c
--- /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 000000000..008ccac3a
--- /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 000000000..88c87c10d
--- /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 000000000..80f370564
--- /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 000000000..7f56725e6
--- /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 000000000..fd4ab1dba
--- /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 000000000..1ffbf3b11
--- /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 000000000..155907291
--- /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 000000000..58347f315
--- /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 000000000..3a7cbf03f
--- /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 000000000..03a4bd0aa
--- /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 000000000..216b60a5e
--- /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 000000000..153723941
--- /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 000000000..c82e53068
--- /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 000000000..a2614e56c
--- /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 000000000..58f2de923
--- /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 000000000..cfccefd24
--- /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 000000000..6fe5ce71a
--- /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 000000000..65cd997a3
--- /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 000000000..3482bfeda
--- /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 000000000..fefeaece8
--- /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 000000000..8975cf35c
--- /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 000000000..d103c4d6a
--- /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 000000000..4c75a0a3a
--- /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 000000000..081f51250
--- /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 aa1f424c8..000000000
--- 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 78de86763..000000000
--- 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 9e8eb52ae..000000000
--- 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 7a031d796..000000000
--- 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 cd6a014cd..000000000
--- 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 c1d644686..000000000
--- 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 f625298d6..000000000
--- 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 436379cb2..000000000
--- 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 cad6f2da6..000000000
--- 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 86ad1594c..000000000
--- 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 847a95ce6..000000000
--- 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 000000000..406956f48
--- /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 000000000..aecea4224
--- /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 000000000..fee860922
--- /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 000000000..851115ac5
--- /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 000000000..7acb6fa5e
--- /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 000000000..bf340fac7
--- /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 000000000..735f8648c
--- /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 000000000..cf3920563
--- /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 000000000..190947cc2
--- /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 000000000..d71de3ac5
--- /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 000000000..68c22122f
--- /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 000000000..28c576e22
--- /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 000000000..10ad40b9c
--- /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 000000000..7ac0beaa7
--- /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 000000000..777ab7c80
--- /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 000000000..0b285caa2
--- /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 } } } */