summaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-08-28 19:14:49 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-10-27 07:56:45 -0700
commitc376fd4175a34c3212ad18a21604a89970938d14 (patch)
tree84ad2663170aacb58297355d7c1faab806e36a36 /gcc/testsuite
parent543d5cb877862a149069011befd5b07fb0d253e7 (diff)
downloadgcc-c376fd4175a34c3212ad18a21604a89970938d14.tar.gz
Load specific external function addresses via GOT slothjl/pic/master
Drawbacks with -fno-plt and noplt attribute are 1. -fno-plt may force locally defined functions to be called via their GOT slots through indirect branch, instead of direct branch. 2. noplt attribute doesn't work on libcalls of builtin functions. 3. noplt attribute requires modifying source codes which may not be desirable for third party source packages. Add -fno-plt=file and -fno-plt=[symbol,...] options to specify which external function addresses should be loaded from the GOT slot to avoid PLT. We don't set REG_EQUAL note with external function symbols whose address are loaded from GOT slots so that load from the GOT slot won't be optimized out by a register load. gcc/ PR target/67400 * Makefile.in (OBJS): Add noplt-symbols.o. * common.opt (fno-plt=): New option. * explow.c (force_reg): Don't set REG_EQUAL if targetm.cannot_set_reg_equal_const returns true. * expr.c (emit_move_insn): Likewise. * noplt-symbols.c: New file. * noplt-symbols.h: Likewise. * target.def (cannot_set_reg_equal_const): New target hook. * toplev.c: Include "noplt-symbols.h". (process_options): Call noplt_symbols_initialize. (toplev::main): Call noplt_symbols_finish. * config/i386/i386-protos.h (ix86_noplt_operand): New. (ix86_noplt_addr_symbol_rtx): Likewise. * config/i386/i386.c: Include "noplt-symbols.h". (ix86_noplt_rtx_p): New function. (ix86_noplt_operand): Likewise. (ix86_noplt_addr_symbol_rtx): Likewise. (ix86_cannot_set_reg_equal_const): Likewise. (ix86_function_ok_for_sibcall): Replace flag_plt with !noplt_decl_p. (ix86_legitimate_address_p): Allow UNSPEC_GOT and UNSPEC_GOTPCREL if ix86_noplt_addr_symbol_rtx doesn't return NULL. (ix86_print_operand_address): Support UNSPEC_GOT and UNSPEC_GOTPCREL if ix86_noplt_addr_symbol_rtx doesn't return NULL. (ix86_expand_move): Load the external function address via the GOT slot if ix86_noplt_operand returns true. (ix86_expand_call): Replace flag_plt and noplt attribute check with !ix86_noplt_rtx_p. (ix86_nopic_noplt_attribute_p): Call ix86_noplt_rtx_p. (TARGET_CANNOT_SET_REG_EQUAL_CONST): New. * config/i386/i386.h (SYMBOL_FLAG_PLT): New. (SYMBOL_REF_PLT_P): Likewise. (SYMBOL_FLAG_NOPLT): Likewise. (SYMBOL_REF_NOPLT_P): Likewise. * doc/tm.texi.in (TARGET_CANNOT_SET_REG_EQUAL_CONST): New hook. * doc/tm.texi: Updated. gcc/testsuite/ PR target/67400 * gcc.target/i386/noplt-5.c: New test. * gcc.target/i386/noplt-6.c: Likweise. * gcc.target/i386/noplt-7.c: Likweise. * gcc.target/i386/noplt-8.c: Likweise. * gcc.target/i386/noplt-9.c: Likweise. * gcc.target/i386/noplt-10.c: Likweise. * gcc.target/i386/noplt-11.c: Likweise. * gcc.target/i386/noplt-12.c: Likweise. * gcc.target/i386/noplt-13.c: Likweise. * gcc.target/i386/noplt-14.c: Likweise. * gcc.target/i386/noplt-15.c: Likweise. * gcc.target/i386/noplt-16.c: Likweise. * gcc.target/i386/noplt-17.c: Likweise. * gcc.target/i386/noplt-18.c: Likweise. * gcc.target/i386/pr67400-1.c: Likweise. * gcc.target/i386/pr67400-2.c: Likewise. * gcc.target/i386/pr67400-3.c: Likewise. * gcc.target/i386/pr67400-4.c: Likewise.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-10.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-11.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-12.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-13.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-14.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-15.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-16.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-17.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-18.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-5.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-6.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-7.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-8.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-9.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr67400-1.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr67400-2.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/pr67400-3.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr67400-4.c14
18 files changed, 266 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/i386/noplt-10.c b/gcc/testsuite/gcc.target/i386/noplt-10.c
new file mode 100644
index 00000000000..a4c316bb91a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-10.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern void bar (void);
+extern void *p;
+
+void
+foo (void)
+{
+ p = &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { { ! ia32 } || r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-11.c b/gcc/testsuite/gcc.target/i386/noplt-11.c
new file mode 100644
index 00000000000..9e4006a11ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-11.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+static void
+bar (void)
+{
+}
+
+void *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-12.c b/gcc/testsuite/gcc.target/i386/noplt-12.c
new file mode 100644
index 00000000000..ce2f01020d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-12.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern int bar;
+
+void *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-13.c b/gcc/testsuite/gcc.target/i386/noplt-13.c
new file mode 100644
index 00000000000..2113e82e18f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-13.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern void bar (void);
+
+int
+__attribute__((regparm(1)))
+foo (void *p)
+{
+ return p == &bar;
+}
+
+/* { dg-final { scan-assembler "cmp\(l|q\)\[ \t\]*bar@GOTPCREL" { target { { ! ia32 } && r_x86_64_gotpcrelx } } } } */
+/* { dg-final { scan-assembler "cmpl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-14.c b/gcc/testsuite/gcc.target/i386/noplt-14.c
new file mode 100644
index 00000000000..ee0217abe78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-14.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern void bar1 (void) asm ("bar");
+
+void
+foo (void)
+{
+ bar1 ();
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-15.c b/gcc/testsuite/gcc.target/i386/noplt-15.c
new file mode 100644
index 00000000000..4fcb460b674
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-15.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern void bar (void) asm ("bar1");
+
+void
+foo (void)
+{
+ bar ();
+}
+
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*.bar1@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*.bar1@GOT" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-16.c b/gcc/testsuite/gcc.target/i386/noplt-16.c
new file mode 100644
index 00000000000..5c70161bb15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-16.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt -fno-plt=bar" } */
+
+extern void bar (void);
+extern void yyy (void);
+
+int
+foo (void)
+{
+ bar ();
+ yyy ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.yyy@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && r_386_got32x } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.yyy@GOT" { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-17.c b/gcc/testsuite/gcc.target/i386/noplt-17.c
new file mode 100644
index 00000000000..16083ed2c01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-17.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -mno-popcnt -fno-pic -fno-plt=__popcountsi2,__popcountdi2" } */
+
+int
+foo (unsigned int i)
+{
+ return __builtin_popcount (i);
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.__popcountdi2@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.__popcountsi2@GOT" { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-18.c b/gcc/testsuite/gcc.target/i386/noplt-18.c
new file mode 100644
index 00000000000..d3e3eb4b1ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-18.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern int bar (void);
+static __typeof(bar) __bar __attribute__ ((__weakref__("bar")));
+
+int
+active_p (void)
+{
+ static void *const active_ptr = __extension__ (void *) &__bar;
+ return active_ptr != 0;
+}
+
+/* { dg-final { scan-assembler "__bar@GOTPCREL" { target { { ! ia32 } && r_x86_64_gotpcrelx } } } } */
+/* { dg-final { scan-assembler "__bar@GOT" { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-5.c b/gcc/testsuite/gcc.target/i386/noplt-5.c
new file mode 100644
index 00000000000..3c7331a215a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-5.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern void bar (void);
+
+void
+foo (void)
+{
+ bar ();
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT" { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-6.c b/gcc/testsuite/gcc.target/i386/noplt-6.c
new file mode 100644
index 00000000000..b61086b34bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-6.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=xxx,bar" } */
+
+extern void bar (void);
+extern void yyy (void);
+
+int
+foo (void)
+{
+ bar ();
+ yyy ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*.yyy@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT" { target { ia32 && r_386_got32x } } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*.yyy@GOT" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-7.c b/gcc/testsuite/gcc.target/i386/noplt-7.c
new file mode 100644
index 00000000000..33600cbc2e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-7.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic -fno-plt=bar" } */
+
+extern void bar (void);
+
+void
+foo (void)
+{
+ bar ();
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOT\\(" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-8.c b/gcc/testsuite/gcc.target/i386/noplt-8.c
new file mode 100644
index 00000000000..e8a3e81e3f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-8.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic -fno-plt=xxx,bar" } */
+
+extern void bar (void);
+extern void yyy (void);
+
+int
+foo (void)
+{
+ bar ();
+ yyy ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*.yyy@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOT\\(" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*.yyy@GOT\\(" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-9.c b/gcc/testsuite/gcc.target/i386/noplt-9.c
new file mode 100644
index 00000000000..a9598fe01f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-9.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt=bar" } */
+
+extern void bar (void);
+
+void *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { { ! ia32 } || r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-1.c b/gcc/testsuite/gcc.target/i386/pr67400-1.c
new file mode 100644
index 00000000000..1b8dfbcf6e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr67400-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern void bar (void);
+
+void *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { { ! ia32 } || r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-2.c b/gcc/testsuite/gcc.target/i386/pr67400-2.c
new file mode 100644
index 00000000000..aa78748491a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr67400-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern void bar (void);
+extern void *p;
+
+void
+foo (void)
+{
+ p = &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { { ! ia32 } || r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-3.c b/gcc/testsuite/gcc.target/i386/pr67400-3.c
new file mode 100644
index 00000000000..b303213f7fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr67400-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+static void
+bar (void)
+{
+}
+
+void *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr67400-4.c b/gcc/testsuite/gcc.target/i386/pr67400-4.c
new file mode 100644
index 00000000000..b2364cf198d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr67400-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fno-plt" } */
+
+extern int bar;
+
+void *
+foo (void)
+{
+ return &bar;
+}
+
+/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar," } } */
+/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]*bar@GOT," { target { ia32 && r_386_got32x } } } } */