public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
@ 2015-02-06 16:23 H.J. Lu
  2015-02-06 21:31 ` Jack Howarth
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-06 16:23 UTC (permalink / raw)
  To: gcc-patches

If a hidden weak symbol isn't defined in the TU, we can't assume it will
be defined in another TU at link time.  It makes a difference in code
generation when compiling for PIC. If we assume that a hidden weak
undefined symbol is local, the address checking may be optimized out and
leads to the wrong code.  This means that a symbol with user specified
visibility is local only if it is locally resolved or defined, not weak
or not compiling for PIC.  When symbol visibility is specified in the
source, we should always output symbol visibility even if symbol isn't
local to the TU.

If a global data symbol is defined in the TU, it is always local to the
executable, regardless if it is a common symbol or not.  If we aren't
compiling for shared library, locally defined global data symbol binds
locally.

Tested on Linux/x86-64.  OK for trunk?

Thanks.


H.J.
---
gcc/

	PR rtl-optimization/32219
	* cgraphunit.c (varpool_node::finalize_decl): Set definition
	first before calling notice_global_symbol so that it is
	available to notice_global_symbol.
	* varasm.c (default_binds_local_p_1): Resolve defined data
	symbol locally if not building shared library.  Resolve symbol
	with user specified visibility locally only if it is locally
	resolved or defined, not weak or not compiling for PIC.
	(default_elf_asm_output_external): Always output visibility
	specified in the source.

gcc/testsuite/

	PR rtl-optimization/32219
	* gcc.dg/visibility-22.c: New test.
	* gcc.dg/visibility-23.c: Likewise.
	* gcc.target/i386/pr32219-1.c: Likewise.
	* gcc.target/i386/pr32219-2.c: Likewise.
	* gcc.target/i386/pr32219-3.c: Likewise.
	* gcc.target/i386/pr32219-4.c: Likewise.
	* gcc.target/i386/pr32219-5.c: Likewise.
	* gcc.target/i386/pr32219-6.c: Likewise.
	* gcc.target/i386/pr32219-7.c: Likewise.
	* gcc.target/i386/pr32219-8.c: Likewise.
	* gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
	of GOT relocation.
---
 gcc/cgraphunit.c                          |  4 +++-
 gcc/testsuite/gcc.dg/visibility-22.c      | 14 +++++++++++++
 gcc/testsuite/gcc.dg/visibility-23.c      | 15 +++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
 gcc/varasm.c                              | 35 ++++++++++++++++++-------------
 13 files changed, 185 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
 create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index a2650f7..e1a6e41 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
new file mode 100644
index 0000000..30087de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-22.c
@@ -0,0 +1,14 @@
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-fPIC" { target fpic } } */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
new file mode 100644
index 0000000..070493f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-23.c
@@ -0,0 +1,15 @@
+/* PR target/32219 */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "foo" } } */
+/* { dg-options "-fPIC" { target fpic } } */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
new file mode 100644
index 0000000..5bd80a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Common symbol with -fpie.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
new file mode 100644
index 0000000..0cf2eb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
new file mode 100644
index 0000000..911f2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak common symbol with -fpie.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
new file mode 100644
index 0000000..3d43439
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
new file mode 100644
index 0000000..ee7442e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Initialized symbol with -fpie.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
new file mode 100644
index 0000000..f261433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
new file mode 100644
index 0000000..12aaf72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak initialized symbol with -fpie.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
new file mode 100644
index 0000000..2e4fba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 46c3c6f..a23e996 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { ia32 } } } */
 /* { dg-options "-O2 -fPIE -pie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index eb65b1f..f7c13af 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6826,11 +6826,17 @@ default_binds_local_p_1 (const_tree exp, int shlib)
       && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
     {
       varpool_node *vnode = varpool_node::get (exp);
-      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
-	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->resolution))
-	resolved_to_local_def = true;
+      /* If not building shared library, common or initialized symbols
+	 are also resolved locally, regardless they are weak or not.  */
+      if (vnode)
+	{
+	  if ((!shlib && vnode->definition)
+	      || vnode->in_other_partition
+	      || resolution_local_p (vnode->resolution))
+	    resolved_locally = true;
+	  if (resolution_to_local_definition_p (vnode->resolution))
+	    resolved_to_local_def = true;
+	}
     }
   else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
     {
@@ -6859,9 +6865,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   else if (! TREE_PUBLIC (exp))
     local_p = true;
   /* A variable is local if the user has said explicitly that it will
-     be.  */
+     be and it is resolved or defined locally, not compiling for PIC or
+     not weak.  */
   else if ((DECL_VISIBILITY_SPECIFIED (exp)
 	    || resolved_to_local_def)
+	   && (resolved_locally
+	       || !flag_pic
+	       || !DECL_EXTERNAL (exp)
+	       || !DECL_WEAK (exp))
 	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     local_p = true;
   /* Variables defined outside this object might not be local.  */
@@ -6880,13 +6891,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
      symbols resolved from other modules.  */
   else if (shlib)
     local_p = false;
-  /* Uninitialized COMMON variable may be unified with symbols
-     resolved from other modules.  */
-  else if (DECL_COMMON (exp)
-	   && !resolved_locally
-	   && (DECL_INITIAL (exp) == NULL
-	       || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
-    local_p = false;
   /* Otherwise we're left with initialized (or non-common) global data
      which is of necessity defined locally.  */
   else
@@ -7445,9 +7449,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.   Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }
 
-- 
1.9.3

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-06 16:23 [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking H.J. Lu
@ 2015-02-06 21:31 ` Jack Howarth
  2015-02-06 21:41   ` H.J. Lu
  0 siblings, 1 reply; 53+ messages in thread
From: Jack Howarth @ 2015-02-06 21:31 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

H.J.,
    On x86_64-apple-darwin14, your patch applied to r220481 results in...

FAIL: gcc.dg/visibility-22.c (test for excess errors)
FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo

with...

Executing on host:
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
 -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC  -lm
-m32  -o ./visibility-22.exe    (timeout = 300)
spawn -ignore SIGHUP
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
-fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -lm -m32
-o ./visibility-22.exe^M
Undefined symbols for architecture i386:^M
  "_foo", referenced from:^M
      _main in ccMD1qjz.o^M
      _main in ccMD1qjz.o^M
ld: symbol(s) not found for architecture i386^M
collect2: error: ld returned 1 exit status^M
compiler exited with status 1
output is:
Undefined symbols for architecture i386:^M
  "_foo", referenced from:^M
      _main in ccMD1qjz.o^M
      _main in ccMD1qjz.o^M
ld: symbol(s) not found for architecture i386^M
collect2: error: ld returned 1 exit status^M

FAIL: gcc.dg/visibility-22.c (test for excess errors)

Executing on host:
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
 -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC -S
-m32  -o visibility-23.s    (timeout = 300)
spawn -ignore SIGHUP
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
-fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
visibility-23.s^M
PASS: gcc.dg/visibility-23.c (test for excess errors)
FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo

        Jack

On Fri, Feb 6, 2015 at 11:23 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> If a hidden weak symbol isn't defined in the TU, we can't assume it will
> be defined in another TU at link time.  It makes a difference in code
> generation when compiling for PIC. If we assume that a hidden weak
> undefined symbol is local, the address checking may be optimized out and
> leads to the wrong code.  This means that a symbol with user specified
> visibility is local only if it is locally resolved or defined, not weak
> or not compiling for PIC.  When symbol visibility is specified in the
> source, we should always output symbol visibility even if symbol isn't
> local to the TU.
>
> If a global data symbol is defined in the TU, it is always local to the
> executable, regardless if it is a common symbol or not.  If we aren't
> compiling for shared library, locally defined global data symbol binds
> locally.
>
> Tested on Linux/x86-64.  OK for trunk?
>
> Thanks.
>
>
> H.J.
> ---
> gcc/
>
>         PR rtl-optimization/32219
>         * cgraphunit.c (varpool_node::finalize_decl): Set definition
>         first before calling notice_global_symbol so that it is
>         available to notice_global_symbol.
>         * varasm.c (default_binds_local_p_1): Resolve defined data
>         symbol locally if not building shared library.  Resolve symbol
>         with user specified visibility locally only if it is locally
>         resolved or defined, not weak or not compiling for PIC.
>         (default_elf_asm_output_external): Always output visibility
>         specified in the source.
>
> gcc/testsuite/
>
>         PR rtl-optimization/32219
>         * gcc.dg/visibility-22.c: New test.
>         * gcc.dg/visibility-23.c: Likewise.
>         * gcc.target/i386/pr32219-1.c: Likewise.
>         * gcc.target/i386/pr32219-2.c: Likewise.
>         * gcc.target/i386/pr32219-3.c: Likewise.
>         * gcc.target/i386/pr32219-4.c: Likewise.
>         * gcc.target/i386/pr32219-5.c: Likewise.
>         * gcc.target/i386/pr32219-6.c: Likewise.
>         * gcc.target/i386/pr32219-7.c: Likewise.
>         * gcc.target/i386/pr32219-8.c: Likewise.
>         * gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
>         of GOT relocation.
> ---
>  gcc/cgraphunit.c                          |  4 +++-
>  gcc/testsuite/gcc.dg/visibility-22.c      | 14 +++++++++++++
>  gcc/testsuite/gcc.dg/visibility-23.c      | 15 +++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
>  gcc/varasm.c                              | 35 ++++++++++++++++++-------------
>  13 files changed, 185 insertions(+), 17 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c
>
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index a2650f7..e1a6e41 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
>
>    if (node->definition)
>      return;
> -  notice_global_symbol (decl);
> +  /* Set definition first before calling notice_global_symbol so that
> +     it is available to notice_global_symbol.  */
>    node->definition = true;
> +  notice_global_symbol (decl);
>    if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
>        /* Traditionally we do not eliminate static variables when not
>          optimizing and when not doing toplevel reoder.  */
> diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
> new file mode 100644
> index 0000000..30087de
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-22.c
> @@ -0,0 +1,14 @@
> +/* PR target/32219 */
> +/* { dg-do run } */
> +/* { dg-require-visibility "" } */
> +/* { dg-options "-fPIC" { target fpic } } */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> +
> diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
> new file mode 100644
> index 0000000..070493f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-23.c
> @@ -0,0 +1,15 @@
> +/* PR target/32219 */
> +/* { dg-do compile } */
> +/* { dg-require-visibility "" } */
> +/* { dg-final { scan-hidden "foo" } } */
> +/* { dg-options "-fPIC" { target fpic } } */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> +
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> new file mode 100644
> index 0000000..5bd80a0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Common symbol with -fpie.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> new file mode 100644
> index 0000000..0cf2eb5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Common symbol with -fpic.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> new file mode 100644
> index 0000000..911f2a5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak common symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> new file mode 100644
> index 0000000..3d43439
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak common symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> new file mode 100644
> index 0000000..ee7442e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Initialized symbol with -fpie.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> new file mode 100644
> index 0000000..f261433
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Initialized symbol with -fpic.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> new file mode 100644
> index 0000000..12aaf72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak initialized symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> new file mode 100644
> index 0000000..2e4fba0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak initialized symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
> index 46c3c6f..a23e996 100644
> --- a/gcc/testsuite/gcc.target/i386/pr64317.c
> +++ b/gcc/testsuite/gcc.target/i386/pr64317.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile { target { ia32 } } } */
>  /* { dg-options "-O2 -fPIE -pie" } */
>  /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
> -/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
> +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
>  /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
>  long c;
>
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index eb65b1f..f7c13af 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6826,11 +6826,17 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>      {
>        varpool_node *vnode = varpool_node::get (exp);
> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
> -       resolved_locally = true;
> -      if (vnode
> -         && resolution_to_local_definition_p (vnode->resolution))
> -       resolved_to_local_def = true;
> +      /* If not building shared library, common or initialized symbols
> +        are also resolved locally, regardless they are weak or not.  */
> +      if (vnode)
> +       {
> +         if ((!shlib && vnode->definition)
> +             || vnode->in_other_partition
> +             || resolution_local_p (vnode->resolution))
> +           resolved_locally = true;
> +         if (resolution_to_local_definition_p (vnode->resolution))
> +           resolved_to_local_def = true;
> +       }
>      }
>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>      {
> @@ -6859,9 +6865,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    else if (! TREE_PUBLIC (exp))
>      local_p = true;
>    /* A variable is local if the user has said explicitly that it will
> -     be.  */
> +     be and it is resolved or defined locally, not compiling for PIC or
> +     not weak.  */
>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>             || resolved_to_local_def)
> +          && (resolved_locally
> +              || !flag_pic
> +              || !DECL_EXTERNAL (exp)
> +              || !DECL_WEAK (exp))
>            && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>      local_p = true;
>    /* Variables defined outside this object might not be local.  */
> @@ -6880,13 +6891,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>       symbols resolved from other modules.  */
>    else if (shlib)
>      local_p = false;
> -  /* Uninitialized COMMON variable may be unified with symbols
> -     resolved from other modules.  */
> -  else if (DECL_COMMON (exp)
> -          && !resolved_locally
> -          && (DECL_INITIAL (exp) == NULL
> -              || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
> -    local_p = false;
>    /* Otherwise we're left with initialized (or non-common) global data
>       which is of necessity defined locally.  */
>    else
> @@ -7445,9 +7449,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>  {
>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>       set in order to avoid putting out names that are never really
> -     used. */
> +     used.   Always output visibility specified in the source.  */
>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> -      && targetm.binds_local_p (decl))
> +      && (DECL_VISIBILITY_SPECIFIED (decl)
> +         || targetm.binds_local_p (decl)))
>      maybe_assemble_visibility (decl);
>  }
>
> --
> 1.9.3
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-06 21:31 ` Jack Howarth
@ 2015-02-06 21:41   ` H.J. Lu
  2015-02-06 21:51     ` Jack Howarth
  2015-02-07  1:51     ` Jack Howarth
  0 siblings, 2 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-06 21:41 UTC (permalink / raw)
  To: Jack Howarth; +Cc: GCC Patches

On Fri, Feb 6, 2015 at 1:31 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
> H.J.,
>     On x86_64-apple-darwin14, your patch applied to r220481 results in...
>
> FAIL: gcc.dg/visibility-22.c (test for excess errors)
> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>
> with...
>
> Executing on host:
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC  -lm
> -m32  -o ./visibility-22.exe    (timeout = 300)
> spawn -ignore SIGHUP
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -lm -m32
> -o ./visibility-22.exe^M
> Undefined symbols for architecture i386:^M
>   "_foo", referenced from:^M
>       _main in ccMD1qjz.o^M
>       _main in ccMD1qjz.o^M
> ld: symbol(s) not found for architecture i386^M
> collect2: error: ld returned 1 exit status^M
> compiler exited with status 1
> output is:
> Undefined symbols for architecture i386:^M
>   "_foo", referenced from:^M
>       _main in ccMD1qjz.o^M
>       _main in ccMD1qjz.o^M
> ld: symbol(s) not found for architecture i386^M
> collect2: error: ld returned 1 exit status^M
>
> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>
> Executing on host:
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC -S
> -m32  -o visibility-23.s    (timeout = 300)
> spawn -ignore SIGHUP
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
> visibility-23.s^M
> PASS: gcc.dg/visibility-23.c (test for excess errors)
> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>

Does Darwin support undefined hidden weak symbol?
Can you compile and gcc/testsuite/gcc.dg/visibility-22.c
with clang on Darwin?

-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-06 21:41   ` H.J. Lu
@ 2015-02-06 21:51     ` Jack Howarth
  2015-02-07  1:50       ` H.J. Lu
  2015-02-07  1:51     ` Jack Howarth
  1 sibling, 1 reply; 53+ messages in thread
From: Jack Howarth @ 2015-02-06 21:51 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

H.J.,
     The clang compilers exhibit the same behavior on these test cases.

Undefined symbols for architecture x86_64:
  "_foo", referenced from:
      _main in visibility-23-e1e564.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

however if I also pass "-Wl,-undefined -Wl,dynamic_lookup" to the
linker, both test
compile and run.
     FYI, the assembly from...

/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
-fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
visibility-23.s

contains...

        .text
        .globl _main
_main:
LFB0:
        pushl   %ebp
LCFI0:
        movl    %esp, %ebp
LCFI1:
        subl    $8, %esp
        call    ___x86.get_pc_thunk.ax
L1$pb:
        leal    L_foo$non_lazy_ptr-L1$pb(%eax), %eax
        movl    (%eax), %eax
        testl   %eax, %eax
        je      L2
        call    _foo
L2:
        movl    $0, %eax
        leave
LCFI2:
        ret
LFE0:
        .weak_reference _foo
        .section __TEXT,__textcoal_nt,coalesced,pure_instructions
        .weak_definition        ___x86.get_pc_thunk.ax
        .private_extern ___x86.get_pc_thunk.ax
___x86.get_pc_thunk.ax:
LFB1:
        movl    (%esp), %eax
        ret
LFE1:
        .section
__TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
        .set L$set$0,LECIE1-LSCIE1
        .long L$set$0
LSCIE1:
        .long   0
        .byte   0x1
        .ascii "zR\0"
        .byte   0x1
        .byte   0x7c
        .byte   0x8
        .byte   0x1
        .byte   0x10
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .byte   0x88
        .byte   0x1
        .align 2
LECIE1:
LSFDE1:
        .set L$set$1,LEFDE1-LASFDE1
        .long L$set$1
LASFDE1:
        .long   LASFDE1-EH_frame1
        .long   LFB0-.
        .set L$set$2,LFE0-LFB0
        .long L$set$2
        .byte   0
        .byte   0x4
        .set L$set$3,LCFI0-LFB0
        .long L$set$3
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$4,LCFI1-LCFI0
        .long L$set$4
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$5,LCFI2-LCFI1
        .long L$set$5
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE1:
LSFDE3:
        .set L$set$6,LEFDE3-LASFDE3
        .long L$set$6
LASFDE3:
        .long   LASFDE3-EH_frame1
        .long   LFB1-.
        .set L$set$7,LFE1-LFB1
        .long L$set$7
        .byte   0
        .align 2
LEFDE3:
        .section __IMPORT,__pointers,non_lazy_symbol_pointers
        .weak_reference _foo
L_foo$non_lazy_ptr:
        .indirect_symbol _foo
        .long   0
        .subsections_via_symbols


On Fri, Feb 6, 2015 at 4:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Feb 6, 2015 at 1:31 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>> H.J.,
>>     On x86_64-apple-darwin14, your patch applied to r220481 results in...
>>
>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>
>> with...
>>
>> Executing on host:
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC  -lm
>> -m32  -o ./visibility-22.exe    (timeout = 300)
>> spawn -ignore SIGHUP
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -lm -m32
>> -o ./visibility-22.exe^M
>> Undefined symbols for architecture i386:^M
>>   "_foo", referenced from:^M
>>       _main in ccMD1qjz.o^M
>>       _main in ccMD1qjz.o^M
>> ld: symbol(s) not found for architecture i386^M
>> collect2: error: ld returned 1 exit status^M
>> compiler exited with status 1
>> output is:
>> Undefined symbols for architecture i386:^M
>>   "_foo", referenced from:^M
>>       _main in ccMD1qjz.o^M
>>       _main in ccMD1qjz.o^M
>> ld: symbol(s) not found for architecture i386^M
>> collect2: error: ld returned 1 exit status^M
>>
>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>
>> Executing on host:
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC -S
>> -m32  -o visibility-23.s    (timeout = 300)
>> spawn -ignore SIGHUP
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
>> visibility-23.s^M
>> PASS: gcc.dg/visibility-23.c (test for excess errors)
>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>
>
> Does Darwin support undefined hidden weak symbol?
> Can you compile and gcc/testsuite/gcc.dg/visibility-22.c
> with clang on Darwin?
>
> --
> H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-06 21:51     ` Jack Howarth
@ 2015-02-07  1:50       ` H.J. Lu
  0 siblings, 0 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-07  1:50 UTC (permalink / raw)
  To: Jack Howarth; +Cc: GCC Patches

On Fri, Feb 6, 2015 at 1:51 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
> H.J.,
>      The clang compilers exhibit the same behavior on these test cases.
>
> Undefined symbols for architecture x86_64:
>   "_foo", referenced from:
>       _main in visibility-23-e1e564.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see invocation)
>
> however if I also pass "-Wl,-undefined -Wl,dynamic_lookup" to the
> linker, both test
> compile and run.
>      FYI, the assembly from...
>
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
> visibility-23.s

Can you give my updated patch:

https://gcc.gnu.org/git/?p=gcc.git;a=patch;h=81a3a94c146950d489e30d07161f6df47959ae7a

a try?

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-06 21:41   ` H.J. Lu
  2015-02-06 21:51     ` Jack Howarth
@ 2015-02-07  1:51     ` Jack Howarth
  2015-02-07  1:55       ` H.J. Lu
  1 sibling, 1 reply; 53+ messages in thread
From: Jack Howarth @ 2015-02-07  1:51 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

H.J.,
     This patch also seems to be causing a huge number of regressions
in the g++ test suite due to linkage warnings on darwin of the form...

ld: warning: direct access in Model::~Model() to global weak symbol
vtable for Model means the weak symbol cannot be overridden at
runtime. This was likely caused by different translation units being
compiled with different visibility settings.

Can this change wait until stage1?
            Jack

On Fri, Feb 6, 2015 at 4:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Feb 6, 2015 at 1:31 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>> H.J.,
>>     On x86_64-apple-darwin14, your patch applied to r220481 results in...
>>
>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>
>> with...
>>
>> Executing on host:
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC  -lm
>> -m32  -o ./visibility-22.exe    (timeout = 300)
>> spawn -ignore SIGHUP
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -lm -m32
>> -o ./visibility-22.exe^M
>> Undefined symbols for architecture i386:^M
>>   "_foo", referenced from:^M
>>       _main in ccMD1qjz.o^M
>>       _main in ccMD1qjz.o^M
>> ld: symbol(s) not found for architecture i386^M
>> collect2: error: ld returned 1 exit status^M
>> compiler exited with status 1
>> output is:
>> Undefined symbols for architecture i386:^M
>>   "_foo", referenced from:^M
>>       _main in ccMD1qjz.o^M
>>       _main in ccMD1qjz.o^M
>> ld: symbol(s) not found for architecture i386^M
>> collect2: error: ld returned 1 exit status^M
>>
>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>
>> Executing on host:
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC -S
>> -m32  -o visibility-23.s    (timeout = 300)
>> spawn -ignore SIGHUP
>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
>> visibility-23.s^M
>> PASS: gcc.dg/visibility-23.c (test for excess errors)
>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>
>
> Does Darwin support undefined hidden weak symbol?
> Can you compile and gcc/testsuite/gcc.dg/visibility-22.c
> with clang on Darwin?
>
> --
> H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07  1:51     ` Jack Howarth
@ 2015-02-07  1:55       ` H.J. Lu
  2015-02-07  2:25         ` Jack Howarth
  2015-02-07  8:28         ` Jack Howarth
  0 siblings, 2 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-07  1:55 UTC (permalink / raw)
  To: Jack Howarth; +Cc: GCC Patches

On Fri, Feb 6, 2015 at 5:51 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
> H.J.,
>      This patch also seems to be causing a huge number of regressions
> in the g++ test suite due to linkage warnings on darwin of the form...
>
> ld: warning: direct access in Model::~Model() to global weak symbol
> vtable for Model means the weak symbol cannot be overridden at
> runtime. This was likely caused by different translation units being
> compiled with different visibility settings.

Can you try my new patch?

> Can this change wait until stage1?
>             Jack
>
> On Fri, Feb 6, 2015 at 4:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Fri, Feb 6, 2015 at 1:31 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>>> H.J.,
>>>     On x86_64-apple-darwin14, your patch applied to r220481 results in...
>>>
>>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>>
>>> with...
>>>
>>> Executing on host:
>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC  -lm
>>> -m32  -o ./visibility-22.exe    (timeout = 300)
>>> spawn -ignore SIGHUP
>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -lm -m32
>>> -o ./visibility-22.exe^M
>>> Undefined symbols for architecture i386:^M
>>>   "_foo", referenced from:^M
>>>       _main in ccMD1qjz.o^M
>>>       _main in ccMD1qjz.o^M
>>> ld: symbol(s) not found for architecture i386^M
>>> collect2: error: ld returned 1 exit status^M
>>> compiler exited with status 1
>>> output is:
>>> Undefined symbols for architecture i386:^M
>>>   "_foo", referenced from:^M
>>>       _main in ccMD1qjz.o^M
>>>       _main in ccMD1qjz.o^M
>>> ld: symbol(s) not found for architecture i386^M
>>> collect2: error: ld returned 1 exit status^M
>>>
>>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>>
>>> Executing on host:
>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC -S
>>> -m32  -o visibility-23.s    (timeout = 300)
>>> spawn -ignore SIGHUP
>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
>>> visibility-23.s^M
>>> PASS: gcc.dg/visibility-23.c (test for excess errors)
>>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>>
>>
>> Does Darwin support undefined hidden weak symbol?
>> Can you compile and gcc/testsuite/gcc.dg/visibility-22.c
>> with clang on Darwin?
>>
>> --
>> H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07  1:55       ` H.J. Lu
@ 2015-02-07  2:25         ` Jack Howarth
  2015-02-07  8:28         ` Jack Howarth
  1 sibling, 0 replies; 53+ messages in thread
From: Jack Howarth @ 2015-02-07  2:25 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

H.J.,
    Where is this new patch?
              Jack

On Fri, Feb 6, 2015 at 8:55 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Feb 6, 2015 at 5:51 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>> H.J.,
>>      This patch also seems to be causing a huge number of regressions
>> in the g++ test suite due to linkage warnings on darwin of the form...
>>
>> ld: warning: direct access in Model::~Model() to global weak symbol
>> vtable for Model means the weak symbol cannot be overridden at
>> runtime. This was likely caused by different translation units being
>> compiled with different visibility settings.
>
> Can you try my new patch?
>
>> Can this change wait until stage1?
>>             Jack
>>
>> On Fri, Feb 6, 2015 at 4:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Fri, Feb 6, 2015 at 1:31 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>>>> H.J.,
>>>>     On x86_64-apple-darwin14, your patch applied to r220481 results in...
>>>>
>>>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>>>
>>>> with...
>>>>
>>>> Executing on host:
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC  -lm
>>>> -m32  -o ./visibility-22.exe    (timeout = 300)
>>>> spawn -ignore SIGHUP
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -lm -m32
>>>> -o ./visibility-22.exe^M
>>>> Undefined symbols for architecture i386:^M
>>>>   "_foo", referenced from:^M
>>>>       _main in ccMD1qjz.o^M
>>>>       _main in ccMD1qjz.o^M
>>>> ld: symbol(s) not found for architecture i386^M
>>>> collect2: error: ld returned 1 exit status^M
>>>> compiler exited with status 1
>>>> output is:
>>>> Undefined symbols for architecture i386:^M
>>>>   "_foo", referenced from:^M
>>>>       _main in ccMD1qjz.o^M
>>>>       _main in ccMD1qjz.o^M
>>>> ld: symbol(s) not found for architecture i386^M
>>>> collect2: error: ld returned 1 exit status^M
>>>>
>>>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>>>
>>>> Executing on host:
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC -S
>>>> -m32  -o visibility-23.s    (timeout = 300)
>>>> spawn -ignore SIGHUP
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
>>>> visibility-23.s^M
>>>> PASS: gcc.dg/visibility-23.c (test for excess errors)
>>>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>>>
>>>
>>> Does Darwin support undefined hidden weak symbol?
>>> Can you compile and gcc/testsuite/gcc.dg/visibility-22.c
>>> with clang on Darwin?
>>>
>>> --
>>> H.J.
>
>
>
> --
> H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07  1:55       ` H.J. Lu
  2015-02-07  2:25         ` Jack Howarth
@ 2015-02-07  8:28         ` Jack Howarth
  2015-02-07 12:27           ` H.J. Lu
  1 sibling, 1 reply; 53+ messages in thread
From: Jack Howarth @ 2015-02-07  8:28 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

H.J.,
     The new patch bootstraps okay on x86_64-apple-darwin14 but I
discovered that you need a small adjustment in the deja-gnu
statements...

 --- /Users/howarth/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
2015-02-06 21:45:04.000000000 -0500
+++ /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
2015-02-07 03:24:42.000000000 -0500
@@ -8,9 +8,9 @@
 /* For kernel modules and static RTPs, the loader treats undefined weak
    symbols in the same way as undefined strong symbols.  The test
    therefore fails to load, so skip it.  */
+/* { dg-options "-fPIC" { target fpic } } */
 /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target
*-*-darwin* } } */
 /* { dg-additional-options "-Wl,-flat_namespace" { target
*-*-darwin[89]* } } */
-/* { dg-options "-fPIC" { target fpic } } */

 extern void foo () __attribute__((weak,visibility("hidden")));
 int

If you don't define a dg-options line first, the dg-additional-options
lines have no effect.
                 Jack

On Fri, Feb 6, 2015 at 8:55 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Feb 6, 2015 at 5:51 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>> H.J.,
>>      This patch also seems to be causing a huge number of regressions
>> in the g++ test suite due to linkage warnings on darwin of the form...
>>
>> ld: warning: direct access in Model::~Model() to global weak symbol
>> vtable for Model means the weak symbol cannot be overridden at
>> runtime. This was likely caused by different translation units being
>> compiled with different visibility settings.
>
> Can you try my new patch?
>
>> Can this change wait until stage1?
>>             Jack
>>
>> On Fri, Feb 6, 2015 at 4:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Fri, Feb 6, 2015 at 1:31 PM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>>>> H.J.,
>>>>     On x86_64-apple-darwin14, your patch applied to r220481 results in...
>>>>
>>>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>>>
>>>> with...
>>>>
>>>> Executing on host:
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC  -lm
>>>> -m32  -o ./visibility-22.exe    (timeout = 300)
>>>> spawn -ignore SIGHUP
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -lm -m32
>>>> -o ./visibility-22.exe^M
>>>> Undefined symbols for architecture i386:^M
>>>>   "_foo", referenced from:^M
>>>>       _main in ccMD1qjz.o^M
>>>>       _main in ccMD1qjz.o^M
>>>> ld: symbol(s) not found for architecture i386^M
>>>> collect2: error: ld returned 1 exit status^M
>>>> compiler exited with status 1
>>>> output is:
>>>> Undefined symbols for architecture i386:^M
>>>>   "_foo", referenced from:^M
>>>>       _main in ccMD1qjz.o^M
>>>>       _main in ccMD1qjz.o^M
>>>> ld: symbol(s) not found for architecture i386^M
>>>> collect2: error: ld returned 1 exit status^M
>>>>
>>>> FAIL: gcc.dg/visibility-22.c (test for excess errors)
>>>>
>>>> Executing on host:
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>>>  -fno-diagnostics-show-caret -fdiagnostics-color=never   -fPIC -S
>>>> -m32  -o visibility-23.s    (timeout = 300)
>>>> spawn -ignore SIGHUP
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/xgcc
>>>> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/
>>>> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-23.c
>>>> -fno-diagnostics-show-caret -fdiagnostics-color=never -fPIC -S -m32 -o
>>>> visibility-23.s^M
>>>> PASS: gcc.dg/visibility-23.c (test for excess errors)
>>>> FAIL: gcc.dg/visibility-23.c scan-hidden private_extern[ \t_]*_?foo
>>>>
>>>
>>> Does Darwin support undefined hidden weak symbol?
>>> Can you compile and gcc/testsuite/gcc.dg/visibility-22.c
>>> with clang on Darwin?
>>>
>>> --
>>> H.J.
>
>
>
> --
> H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07  8:28         ` Jack Howarth
@ 2015-02-07 12:27           ` H.J. Lu
  2015-02-07 15:11             ` Jack Howarth
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-07 12:27 UTC (permalink / raw)
  To: Jack Howarth; +Cc: GCC Patches

On Sat, Feb 07, 2015 at 03:28:38AM -0500, Jack Howarth wrote:
> H.J.,
>      The new patch bootstraps okay on x86_64-apple-darwin14 but I

Does it cause any regressions on x86_64-apple-darwin14?

> discovered that you need a small adjustment in the deja-gnu
> statements...
> 
>  --- /Users/howarth/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
> 2015-02-06 21:45:04.000000000 -0500
> +++ /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
> 2015-02-07 03:24:42.000000000 -0500
> @@ -8,9 +8,9 @@
>  /* For kernel modules and static RTPs, the loader treats undefined weak
>     symbols in the same way as undefined strong symbols.  The test
>     therefore fails to load, so skip it.  */
> +/* { dg-options "-fPIC" { target fpic } } */
>  /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target
> *-*-darwin* } } */
>  /* { dg-additional-options "-Wl,-flat_namespace" { target
> *-*-darwin[89]* } } */
> -/* { dg-options "-fPIC" { target fpic } } */
> 
>  extern void foo () __attribute__((weak,visibility("hidden")));
>  int
> 
> If you don't define a dg-options line first, the dg-additional-options
> lines have no effect.
>                  Jack

Here is the updated patch.

H.J.
---
From 8e61705db8177d41fac45dbeffa4faf6163d4c94 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 5 Feb 2015 14:28:58 -0800
Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC

If a hidden weak symbol isn't defined in the TU, we can't assume it will
be defined in another TU at link time.  It makes a difference in code
generation when compiling for PIC. If we assume that a hidden weak
undefined symbol is local, the address checking may be optimized out and
leads to the wrong code.  This means that a symbol with user specified
visibility is local only if it is locally resolved or defined, not weak
or not compiling for PIC.  When symbol visibility is specified in the
source, we should always output symbol visibility even if symbol isn't
local to the TU.

If a global data symbol is defined in the TU, it is always local to the
executable, regardless if it is a common symbol or not.  If we aren't
compiling for shared library, locally defined global data symbol binds
locally.

gcc/

	PR rtl-optimization/32219
	* cgraphunit.c (varpool_node::finalize_decl): Set definition
	first before calling notice_global_symbol so that it is
	available to notice_global_symbol.
	* varasm.c (default_binds_local_p_1): Resolve defined data
	symbol locally if not building shared library.  Resolve symbol
	with user specified visibility locally only if it is locally
	resolved or defined, not weak or not compiling for PIC.
	(default_elf_asm_output_external): Always output visibility
	specified in the source.
	* config/darwin-protos.h (darwin_output_external): New.
	* config/darwin.c (darwin_output_external): Likewise.
	* config/darwin.h (ASM_OUTPUT_EXTERNAL): Likewise.

gcc/testsuite/

	PR rtl-optimization/32219
	* gcc.dg/visibility-22.c: New test.
	* gcc.dg/visibility-23.c: Likewise.
	* gcc.target/i386/pr32219-1.c: Likewise.
	* gcc.target/i386/pr32219-2.c: Likewise.
	* gcc.target/i386/pr32219-3.c: Likewise.
	* gcc.target/i386/pr32219-4.c: Likewise.
	* gcc.target/i386/pr32219-5.c: Likewise.
	* gcc.target/i386/pr32219-6.c: Likewise.
	* gcc.target/i386/pr32219-7.c: Likewise.
	* gcc.target/i386/pr32219-8.c: Likewise.
	* gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
	of GOT relocation.
---
 gcc/cgraphunit.c                          |  4 +++-
 gcc/config/darwin-protos.h                |  1 +
 gcc/config/darwin.c                       | 15 +++++++++++++
 gcc/config/darwin.h                       |  9 ++++++++
 gcc/testsuite/gcc.dg/visibility-22.c      | 22 +++++++++++++++++++
 gcc/testsuite/gcc.dg/visibility-23.c      | 14 +++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
 gcc/varasm.c                              | 35 ++++++++++++++++++-------------
 16 files changed, 217 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
 create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 35b244e..71367a3 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index 249b9c1..10a77fc 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -89,6 +89,7 @@ extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
 extern void machopic_output_stub (FILE *, const char *, const char *);
 extern void darwin_globalize_label (FILE *, const char *);
 extern void darwin_assemble_visibility (tree, int);
+extern void darwin_output_external (FILE *, tree, const char *name);
 
 extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
 					   const char *);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 40804b8..5025ef7 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -2762,6 +2762,21 @@ darwin_assemble_visibility (tree decl, int vis)
 	     "not supported in this configuration; ignored");
 }
 
+/* Emit text to declare externally defined symbols.  Used to support
+   undefined hidden visibility with Darwin's private extern feature.  */
+
+void
+darwin_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl,
+			const char *name ATTRIBUTE_UNUSED)
+{
+  /* We output the name if and only if TREE_SYMBOL_REFERENCED is set and
+     visibility is specified in the source in order to avoid putting out
+     names that are never really used.  */
+  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+      && DECL_VISIBILITY_SPECIFIED (decl))
+    darwin_assemble_visibility (decl, DECL_VISIBILITY (decl));
+}
+
 /* vec used by darwin_asm_dwarf_section.
    Maybe a hash tab would be better here - but the intention is that this is
    a very short list (fewer than 16 items) and each entry should (ideally, 
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index b61dbb5..c9a1b34 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -700,6 +700,15 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
 #define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
 
+/* A C statement (sans semicolon) to output to the stdio stream STREAM
+   any text necessary for declaring the name of an external symbol
+   named NAME which is referenced in this compilation but not defined.
+   Used to support undefined hidden visibility with Darwin's private
+   extern feature.  */
+
+#undef ASM_OUTPUT_EXTERNAL
+#define ASM_OUTPUT_EXTERNAL darwin_output_external
+
 /* Extra attributes for Darwin.  */
 #define SUBTARGET_ATTRIBUTE_TABLE					     \
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
new file mode 100644
index 0000000..a118a6e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-22.c
@@ -0,0 +1,22 @@
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* This test requires support for undefined weak symbols.  This support
+   is not available on hppa*-*-hpux*.  The test is skipped rather than
+   xfailed to suppress the warning that would otherwise arise.  */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }  */
+/* For kernel modules and static RTPs, the loader treats undefined weak
+   symbols in the same way as undefined strong symbols.  The test
+   therefore fails to load, so skip it.  */
+/* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
+/* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
new file mode 100644
index 0000000..347578e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-23.c
@@ -0,0 +1,14 @@
+/* PR target/32219 */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "foo" } } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
new file mode 100644
index 0000000..5bd80a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Common symbol with -fpie.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
new file mode 100644
index 0000000..0cf2eb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
new file mode 100644
index 0000000..911f2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak common symbol with -fpie.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
new file mode 100644
index 0000000..3d43439
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
new file mode 100644
index 0000000..ee7442e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Initialized symbol with -fpie.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
new file mode 100644
index 0000000..f261433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
new file mode 100644
index 0000000..12aaf72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak initialized symbol with -fpie.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
new file mode 100644
index 0000000..2e4fba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 33f5b5d..32969fc 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { *-*-linux* && ia32 } } } */
 /* { dg-options "-O2 -fpie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index eb65b1f..f7c13af 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6826,11 +6826,17 @@ default_binds_local_p_1 (const_tree exp, int shlib)
       && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
     {
       varpool_node *vnode = varpool_node::get (exp);
-      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
-	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->resolution))
-	resolved_to_local_def = true;
+      /* If not building shared library, common or initialized symbols
+	 are also resolved locally, regardless they are weak or not.  */
+      if (vnode)
+	{
+	  if ((!shlib && vnode->definition)
+	      || vnode->in_other_partition
+	      || resolution_local_p (vnode->resolution))
+	    resolved_locally = true;
+	  if (resolution_to_local_definition_p (vnode->resolution))
+	    resolved_to_local_def = true;
+	}
     }
   else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
     {
@@ -6859,9 +6865,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   else if (! TREE_PUBLIC (exp))
     local_p = true;
   /* A variable is local if the user has said explicitly that it will
-     be.  */
+     be and it is resolved or defined locally, not compiling for PIC or
+     not weak.  */
   else if ((DECL_VISIBILITY_SPECIFIED (exp)
 	    || resolved_to_local_def)
+	   && (resolved_locally
+	       || !flag_pic
+	       || !DECL_EXTERNAL (exp)
+	       || !DECL_WEAK (exp))
 	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     local_p = true;
   /* Variables defined outside this object might not be local.  */
@@ -6880,13 +6891,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
      symbols resolved from other modules.  */
   else if (shlib)
     local_p = false;
-  /* Uninitialized COMMON variable may be unified with symbols
-     resolved from other modules.  */
-  else if (DECL_COMMON (exp)
-	   && !resolved_locally
-	   && (DECL_INITIAL (exp) == NULL
-	       || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
-    local_p = false;
   /* Otherwise we're left with initialized (or non-common) global data
      which is of necessity defined locally.  */
   else
@@ -7445,9 +7449,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.   Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07 12:27           ` H.J. Lu
@ 2015-02-07 15:11             ` Jack Howarth
  2015-02-07 15:25               ` Jack Howarth
  2015-02-07 15:56               ` H.J. Lu
  0 siblings, 2 replies; 53+ messages in thread
From: Jack Howarth @ 2015-02-07 15:11 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches, Mike Stump, Iain Sandoe

H.J,,
    Unfortunately, the answer is yes. This patch still introduces
regressions in the g++ test suite.l These are all some form of...

Executing on host:
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
 -fno-diagnostics-show-caret -fdiagnostics-color=never  -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
-fmessage-length=0  -std=gnu++98 -fabi-version=0
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
 -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
 -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
 -multiply_defined suppress -lm   -m32  -o ./empty7.exe    (timeout =
300)
spawn -ignore SIGHUP
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
-fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
-fmessage-length=0 -std=gnu++98 -fabi-version=0
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-multiply_defined suppress -lm -m32 -o ./empty7.exe^M
ld: warning: direct access in S2::S2()    to global weak symbol vtable
for S2 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S8::S8()    to global weak symbol vtable
for S8 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
output is:
ld: warning: direct access in S2::S2()    to global weak symbol vtable
for S2 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M
ld: warning: direct access in S8::S8()    to global weak symbol vtable
for S8 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.^M


FAIL: g++.dg/abi/empty7.C  -std=gnu++98 (test for excess errors)

Darwin has really twitchy support weak symbol support so any major
rewrite will definitely be stage 1 material and likely require us to
contact the darwin linker developer at Apple for a consultation on the
meaning of these linker warnings.
            Jack



On Sat, Feb 7, 2015 at 7:27 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sat, Feb 07, 2015 at 03:28:38AM -0500, Jack Howarth wrote:
>> H.J.,
>>      The new patch bootstraps okay on x86_64-apple-darwin14 but I
>
> Does it cause any regressions on x86_64-apple-darwin14?
>
>> discovered that you need a small adjustment in the deja-gnu
>> statements...
>>
>>  --- /Users/howarth/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>> 2015-02-06 21:45:04.000000000 -0500
>> +++ /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>> 2015-02-07 03:24:42.000000000 -0500
>> @@ -8,9 +8,9 @@
>>  /* For kernel modules and static RTPs, the loader treats undefined weak
>>     symbols in the same way as undefined strong symbols.  The test
>>     therefore fails to load, so skip it.  */
>> +/* { dg-options "-fPIC" { target fpic } } */
>>  /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target
>> *-*-darwin* } } */
>>  /* { dg-additional-options "-Wl,-flat_namespace" { target
>> *-*-darwin[89]* } } */
>> -/* { dg-options "-fPIC" { target fpic } } */
>>
>>  extern void foo () __attribute__((weak,visibility("hidden")));
>>  int
>>
>> If you don't define a dg-options line first, the dg-additional-options
>> lines have no effect.
>>                  Jack
>
> Here is the updated patch.
>
> H.J.
> ---
> From 8e61705db8177d41fac45dbeffa4faf6163d4c94 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 5 Feb 2015 14:28:58 -0800
> Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC
>
> If a hidden weak symbol isn't defined in the TU, we can't assume it will
> be defined in another TU at link time.  It makes a difference in code
> generation when compiling for PIC. If we assume that a hidden weak
> undefined symbol is local, the address checking may be optimized out and
> leads to the wrong code.  This means that a symbol with user specified
> visibility is local only if it is locally resolved or defined, not weak
> or not compiling for PIC.  When symbol visibility is specified in the
> source, we should always output symbol visibility even if symbol isn't
> local to the TU.
>
> If a global data symbol is defined in the TU, it is always local to the
> executable, regardless if it is a common symbol or not.  If we aren't
> compiling for shared library, locally defined global data symbol binds
> locally.
>
> gcc/
>
>         PR rtl-optimization/32219
>         * cgraphunit.c (varpool_node::finalize_decl): Set definition
>         first before calling notice_global_symbol so that it is
>         available to notice_global_symbol.
>         * varasm.c (default_binds_local_p_1): Resolve defined data
>         symbol locally if not building shared library.  Resolve symbol
>         with user specified visibility locally only if it is locally
>         resolved or defined, not weak or not compiling for PIC.
>         (default_elf_asm_output_external): Always output visibility
>         specified in the source.
>         * config/darwin-protos.h (darwin_output_external): New.
>         * config/darwin.c (darwin_output_external): Likewise.
>         * config/darwin.h (ASM_OUTPUT_EXTERNAL): Likewise.
>
> gcc/testsuite/
>
>         PR rtl-optimization/32219
>         * gcc.dg/visibility-22.c: New test.
>         * gcc.dg/visibility-23.c: Likewise.
>         * gcc.target/i386/pr32219-1.c: Likewise.
>         * gcc.target/i386/pr32219-2.c: Likewise.
>         * gcc.target/i386/pr32219-3.c: Likewise.
>         * gcc.target/i386/pr32219-4.c: Likewise.
>         * gcc.target/i386/pr32219-5.c: Likewise.
>         * gcc.target/i386/pr32219-6.c: Likewise.
>         * gcc.target/i386/pr32219-7.c: Likewise.
>         * gcc.target/i386/pr32219-8.c: Likewise.
>         * gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
>         of GOT relocation.
> ---
>  gcc/cgraphunit.c                          |  4 +++-
>  gcc/config/darwin-protos.h                |  1 +
>  gcc/config/darwin.c                       | 15 +++++++++++++
>  gcc/config/darwin.h                       |  9 ++++++++
>  gcc/testsuite/gcc.dg/visibility-22.c      | 22 +++++++++++++++++++
>  gcc/testsuite/gcc.dg/visibility-23.c      | 14 +++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
>  gcc/varasm.c                              | 35 ++++++++++++++++++-------------
>  16 files changed, 217 insertions(+), 17 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c
>
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 35b244e..71367a3 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
>
>    if (node->definition)
>      return;
> -  notice_global_symbol (decl);
> +  /* Set definition first before calling notice_global_symbol so that
> +     it is available to notice_global_symbol.  */
>    node->definition = true;
> +  notice_global_symbol (decl);
>    if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
>        /* Traditionally we do not eliminate static variables when not
>          optimizing and when not doing toplevel reoder.  */
> diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
> index 249b9c1..10a77fc 100644
> --- a/gcc/config/darwin-protos.h
> +++ b/gcc/config/darwin-protos.h
> @@ -89,6 +89,7 @@ extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
>  extern void machopic_output_stub (FILE *, const char *, const char *);
>  extern void darwin_globalize_label (FILE *, const char *);
>  extern void darwin_assemble_visibility (tree, int);
> +extern void darwin_output_external (FILE *, tree, const char *name);
>
>  extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
>                                            const char *);
> diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
> index 40804b8..5025ef7 100644
> --- a/gcc/config/darwin.c
> +++ b/gcc/config/darwin.c
> @@ -2762,6 +2762,21 @@ darwin_assemble_visibility (tree decl, int vis)
>              "not supported in this configuration; ignored");
>  }
>
> +/* Emit text to declare externally defined symbols.  Used to support
> +   undefined hidden visibility with Darwin's private extern feature.  */
> +
> +void
> +darwin_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl,
> +                       const char *name ATTRIBUTE_UNUSED)
> +{
> +  /* We output the name if and only if TREE_SYMBOL_REFERENCED is set and
> +     visibility is specified in the source in order to avoid putting out
> +     names that are never really used.  */
> +  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> +      && DECL_VISIBILITY_SPECIFIED (decl))
> +    darwin_assemble_visibility (decl, DECL_VISIBILITY (decl));
> +}
> +
>  /* vec used by darwin_asm_dwarf_section.
>     Maybe a hash tab would be better here - but the intention is that this is
>     a very short list (fewer than 16 items) and each entry should (ideally,
> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
> index b61dbb5..c9a1b34 100644
> --- a/gcc/config/darwin.h
> +++ b/gcc/config/darwin.h
> @@ -700,6 +700,15 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
>  #undef TARGET_ASM_ASSEMBLE_VISIBILITY
>  #define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
>
> +/* A C statement (sans semicolon) to output to the stdio stream STREAM
> +   any text necessary for declaring the name of an external symbol
> +   named NAME which is referenced in this compilation but not defined.
> +   Used to support undefined hidden visibility with Darwin's private
> +   extern feature.  */
> +
> +#undef ASM_OUTPUT_EXTERNAL
> +#define ASM_OUTPUT_EXTERNAL darwin_output_external
> +
>  /* Extra attributes for Darwin.  */
>  #define SUBTARGET_ATTRIBUTE_TABLE                                           \
>    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
> diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
> new file mode 100644
> index 0000000..a118a6e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-22.c
> @@ -0,0 +1,22 @@
> +/* PR target/32219 */
> +/* { dg-do run } */
> +/* { dg-require-visibility "" } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +/* This test requires support for undefined weak symbols.  This support
> +   is not available on hppa*-*-hpux*.  The test is skipped rather than
> +   xfailed to suppress the warning that would otherwise arise.  */
> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }  */
> +/* For kernel modules and static RTPs, the loader treats undefined weak
> +   symbols in the same way as undefined strong symbols.  The test
> +   therefore fails to load, so skip it.  */
> +/* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
> +/* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
> new file mode 100644
> index 0000000..347578e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-23.c
> @@ -0,0 +1,14 @@
> +/* PR target/32219 */
> +/* { dg-do compile } */
> +/* { dg-require-visibility "" } */
> +/* { dg-final { scan-hidden "foo" } } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> new file mode 100644
> index 0000000..5bd80a0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Common symbol with -fpie.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> new file mode 100644
> index 0000000..0cf2eb5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Common symbol with -fpic.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> new file mode 100644
> index 0000000..911f2a5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak common symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> new file mode 100644
> index 0000000..3d43439
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak common symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> new file mode 100644
> index 0000000..ee7442e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Initialized symbol with -fpie.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> new file mode 100644
> index 0000000..f261433
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Initialized symbol with -fpic.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> new file mode 100644
> index 0000000..12aaf72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak initialized symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> new file mode 100644
> index 0000000..2e4fba0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak initialized symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
> index 33f5b5d..32969fc 100644
> --- a/gcc/testsuite/gcc.target/i386/pr64317.c
> +++ b/gcc/testsuite/gcc.target/i386/pr64317.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile { target { *-*-linux* && ia32 } } } */
>  /* { dg-options "-O2 -fpie" } */
>  /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
> -/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
> +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
>  /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
>  long c;
>
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index eb65b1f..f7c13af 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6826,11 +6826,17 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>      {
>        varpool_node *vnode = varpool_node::get (exp);
> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
> -       resolved_locally = true;
> -      if (vnode
> -         && resolution_to_local_definition_p (vnode->resolution))
> -       resolved_to_local_def = true;
> +      /* If not building shared library, common or initialized symbols
> +        are also resolved locally, regardless they are weak or not.  */
> +      if (vnode)
> +       {
> +         if ((!shlib && vnode->definition)
> +             || vnode->in_other_partition
> +             || resolution_local_p (vnode->resolution))
> +           resolved_locally = true;
> +         if (resolution_to_local_definition_p (vnode->resolution))
> +           resolved_to_local_def = true;
> +       }
>      }
>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>      {
> @@ -6859,9 +6865,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    else if (! TREE_PUBLIC (exp))
>      local_p = true;
>    /* A variable is local if the user has said explicitly that it will
> -     be.  */
> +     be and it is resolved or defined locally, not compiling for PIC or
> +     not weak.  */
>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>             || resolved_to_local_def)
> +          && (resolved_locally
> +              || !flag_pic
> +              || !DECL_EXTERNAL (exp)
> +              || !DECL_WEAK (exp))
>            && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>      local_p = true;
>    /* Variables defined outside this object might not be local.  */
> @@ -6880,13 +6891,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>       symbols resolved from other modules.  */
>    else if (shlib)
>      local_p = false;
> -  /* Uninitialized COMMON variable may be unified with symbols
> -     resolved from other modules.  */
> -  else if (DECL_COMMON (exp)
> -          && !resolved_locally
> -          && (DECL_INITIAL (exp) == NULL
> -              || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
> -    local_p = false;
>    /* Otherwise we're left with initialized (or non-common) global data
>       which is of necessity defined locally.  */
>    else
> @@ -7445,9 +7449,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>  {
>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>       set in order to avoid putting out names that are never really
> -     used. */
> +     used.   Always output visibility specified in the source.  */
>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> -      && targetm.binds_local_p (decl))
> +      && (DECL_VISIBILITY_SPECIFIED (decl)
> +         || targetm.binds_local_p (decl)))
>      maybe_assemble_visibility (decl);
>  }
>
> --
> 2.1.0
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07 15:11             ` Jack Howarth
@ 2015-02-07 15:25               ` Jack Howarth
  2015-02-07 15:56               ` H.J. Lu
  1 sibling, 0 replies; 53+ messages in thread
From: Jack Howarth @ 2015-02-07 15:25 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches, Mike Stump, Iain Sandoe

H.J.,
     In case it clarifies things at all, the falling testcase...

% /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
-fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
-fmessage-length=0 -std=gnu++98 -fabi-version=0
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
-multiply_defined suppress -lm -m32 -o ./empty7.exe

produces the linker warnings...

ld: warning: direct access in S2::S2()    to global weak symbol vtable
for S2 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol vtable
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S5::S5()    to global weak symbol VTT
for S5 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.
ld: warning: direct access in S8::S8()    to global weak symbol vtable
for S8 means the weak symbol cannot be overridden at runtime. This was
likely caused by different translation units being compiled with
different visibility settings.

when linking the code from empty7.o generated the following assembly in empty7.s

        .section __TEXT,__textcoal_nt,coalesced,pure_instructions
        .align 1
        .globl __ZN2S21fEv
        .weak_definition __ZN2S21fEv
__ZN2S21fEv:
LFB0:
        pushl   %ebp
LCFI0:
        movl    %esp, %ebp
LCFI1:
        call    ___x86.get_pc_thunk.ax
L1$pb:
        nop
        popl    %ebp
LCFI2:
        ret
LFE0:
        .align 1
        .globl __ZN2S7C2Ev
        .weak_definition __ZN2S7C2Ev
__ZN2S7C2Ev:
LFB3:
        pushl   %ebp
LCFI3:
        movl    %esp, %ebp
LCFI4:
        call    ___x86.get_pc_thunk.ax
L2$pb:
        nop
        popl    %ebp
LCFI5:
        ret
LFE3:
        .align 1
        .globl __ZN2S1C2Ev
        .weak_definition __ZN2S1C2Ev
__ZN2S1C2Ev:
LFB6:
        pushl   %ebp
LCFI6:
        movl    %esp, %ebp
LCFI7:
        call    ___x86.get_pc_thunk.ax
L3$pb:
        nop
        popl    %ebp
LCFI8:
        ret
LFE6:
        .align 1
        .globl __ZN2S2C2Ev
        .weak_definition __ZN2S2C2Ev
__ZN2S2C2Ev:
LFB11:
        pushl   %ebp
LCFI9:
        movl    %esp, %ebp
LCFI10:
        call    ___x86.get_pc_thunk.ax
L4$pb:
        movl    8(%ebp), %edx
        leal    __ZTV2S2-L4$pb(%eax), %eax
        leal    8(%eax), %eax
        movl    %eax, (%edx)
        nop
        popl    %ebp
LCFI11:
        ret
LFE11:
        .align 1
        .globl __ZN2S4C2Ev
        .weak_definition __ZN2S4C2Ev
__ZN2S4C2Ev:
LFB14:
        pushl   %ebp
LCFI12:
        movl    %esp, %ebp
LCFI13:
        call    ___x86.get_pc_thunk.ax
L5$pb:
        movl    12(%ebp), %eax
        movl    (%eax), %edx
        movl    8(%ebp), %eax
        movl    %edx, (%eax)
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        subl    $12, %eax
        movl    (%eax), %eax
        movl    %eax, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        movl    12(%ebp), %eax
        movl    4(%eax), %eax
        movl    %eax, (%edx)
        nop
        popl    %ebp
LCFI14:
        ret
LFE14:
        .align 1
        .globl __ZN2S3C2Ev
        .weak_definition __ZN2S3C2Ev
__ZN2S3C2Ev:
LFB17:
        pushl   %ebp
LCFI15:
        movl    %esp, %ebp
LCFI16:
        call    ___x86.get_pc_thunk.ax
L6$pb:
        movl    12(%ebp), %eax
        movl    (%eax), %edx
        movl    8(%ebp), %eax
        movl    %edx, (%eax)
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        subl    $12, %eax
        movl    (%eax), %eax
        movl    %eax, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        movl    12(%ebp), %eax
        movl    4(%eax), %eax
        movl    %eax, (%edx)
        nop
        popl    %ebp
LCFI17:
        ret
LFE17:
        .align 1
        .globl __ZN2S5C1Ev
        .weak_definition __ZN2S5C1Ev
__ZN2S5C1Ev:
LFB20:
        pushl   %ebp
LCFI18:
        movl    %esp, %ebp
LCFI19:
        pushl   %ebx
        subl    $4, %esp
LCFI20:
        call    ___x86.get_pc_thunk.bx
L7$pb:
        movl    8(%ebp), %eax
        addl    $4, %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S2C2Ev
        addl    $16, %esp
        leal    __ZTT2S5-L7$pb(%ebx), %eax
        leal    20(%eax), %eax
        movl    8(%ebp), %edx
        addl    $12, %edx
        subl    $8, %esp
        pushl   %eax
        pushl   %edx
        call    __ZN2S4C2Ev
        addl    $16, %esp
        leal    __ZTT2S5-L7$pb(%ebx), %eax
        leal    4(%eax), %eax
        movl    8(%ebp), %edx
        subl    $8, %esp
        pushl   %eax
        pushl   %edx
        call    __ZN2S3C2Ev
        addl    $16, %esp
        leal    __ZTV2S5-L7$pb(%ebx), %eax
        leal    16(%eax), %eax
        movl    8(%ebp), %edx
        movl    %eax, (%edx)
        movl    $4, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        leal    __ZTV2S5-L7$pb(%ebx), %eax
        leal    28(%eax), %eax
        movl    %eax, (%edx)
        movl    $12, %edx
        movl    8(%ebp), %eax
        addl    %eax, %edx
        leal    __ZTV2S5-L7$pb(%ebx), %eax
        leal    44(%eax), %eax
        movl    %eax, (%edx)
        nop
        movl    -4(%ebp), %ebx
        leave
LCFI21:
        ret
LFE20:
        .align 1
        .globl __ZN2S6C2Ev
        .weak_definition __ZN2S6C2Ev
__ZN2S6C2Ev:
LFB21:
        pushl   %ebp
LCFI22:
        movl    %esp, %ebp
LCFI23:
        subl    $8, %esp
        call    ___x86.get_pc_thunk.ax
L8$pb:
        movl    8(%ebp), %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S5C1Ev
        addl    $16, %esp
        nop
        leave
LCFI24:
        ret
LFE21:
        .align 1
        .globl __ZN2S8C1Ev
        .weak_definition __ZN2S8C1Ev
__ZN2S8C1Ev:
LFB24:
        pushl   %ebp
LCFI25:
        movl    %esp, %ebp
LCFI26:
        pushl   %ebx
        subl    $4, %esp
LCFI27:
        call    ___x86.get_pc_thunk.bx
L9$pb:
        movl    8(%ebp), %eax
        addl    $24, %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S7C2Ev
        addl    $16, %esp
        subl    $12, %esp
        pushl   8(%ebp)
        call    __ZN2S1C2Ev
        addl    $16, %esp
        movl    8(%ebp), %eax
        addl    $4, %eax
        subl    $12, %esp
        pushl   %eax
        call    __ZN2S6C2Ev
        addl    $16, %esp
        leal    __ZTV2S8-L9$pb(%ebx), %eax
        leal    12(%eax), %eax
        movl    8(%ebp), %edx
        movl    %eax, (%edx)
        nop
        movl    -4(%ebp), %ebx
        leave
LCFI28:
        ret
LFE24:
        .globl _s8
        .zerofill __DATA,__pu_bss5,_s8,32,5
        .text
        .globl _main
_main:
LFB25:
        pushl   %ebp
LCFI29:
        movl    %esp, %ebp
LCFI30:
        call    ___x86.get_pc_thunk.ax
L10$pb:
        movl    $0, %eax
        popl    %ebp
LCFI31:
        ret
LFE25:
        .globl __ZTV2S8
        .weak_definition __ZTV2S8
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTV2S8:
        .long   24
        .long   0
        .long   __ZTI2S8
        .globl __ZTT2S8
        .weak_definition __ZTT2S8
        .align 2
__ZTT2S8:
        .long   __ZTV2S8+12
        .globl __ZTV2S5
        .weak_definition __ZTV2S5
        .align 2
__ZTV2S5:
        .long   12
        .long   4
        .long   0
        .long   __ZTI2S5
        .long   0
        .long   -4
        .long   __ZTI2S5
        .long   __ZN2S21fEv
        .long   -8
        .long   -12
        .long   __ZTI2S5
        .globl __ZTT2S5
        .weak_definition __ZTT2S5
        .align 2
__ZTT2S5:
        .long   __ZTV2S5+16
        .long   __ZTC2S50_2S3+12
        .long   __ZTC2S50_2S3+24
        .long   __ZTV2S5+28
        .long   __ZTV2S5+44
        .long   __ZTC2S512_2S4+12
        .long   __ZTC2S512_2S4+24
        .private_extern __ZTC2S50_2S3
        .globl __ZTC2S50_2S3
        .weak_definition __ZTC2S50_2S3
        .align 2
__ZTC2S50_2S3:
        .long   4
        .long   0
        .long   __ZTI2S3
        .long   0
        .long   -4
        .long   __ZTI2S3
        .long   __ZN2S21fEv
        .private_extern __ZTC2S512_2S4
        .globl __ZTC2S512_2S4
        .weak_definition __ZTC2S512_2S4
        .align 2
__ZTC2S512_2S4:
        .long   -8
        .long   0
        .long   __ZTI2S4
        .long   0
        .long   8
        .long   __ZTI2S4
        .long   __ZN2S21fEv
        .globl __ZTV2S2
        .weak_definition __ZTV2S2
        .align 2
__ZTV2S2:
        .long   0
        .long   __ZTI2S2
        .long   __ZN2S21fEv
        .globl __ZTI2S8
        .weak_definition __ZTI2S8
        .align 2
__ZTI2S8:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S8
        .long   0
        .long   3
        .long   __ZTI2S1
        .long   2
        .long   __ZTI2S6
        .long   1026
        .long   __ZTI2S7
        .long   -3069
        .globl __ZTS2S8
        .weak_definition __ZTS2S8
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S8:
        .ascii "2S8\0"
        .globl __ZTI2S5
        .weak_definition __ZTI2S5
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S5:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S5
        .long   2
        .long   2
        .long   __ZTI2S3
        .long   2
        .long   __ZTI2S4
        .long   -4093
        .globl __ZTS2S5
        .weak_definition __ZTS2S5
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S5:
        .ascii "2S5\0"
        .globl __ZTI2S4
        .weak_definition __ZTI2S4
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S4:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S4
        .long   0
        .long   1
        .long   __ZTI2S2
        .long   -3069
        .globl __ZTS2S4
        .weak_definition __ZTS2S4
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S4:
        .ascii "2S4\0"
        .globl __ZTI2S3
        .weak_definition __ZTI2S3
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S3:
        .long   __ZTVN10__cxxabiv121__vmi_class_type_infoE+8
        .long   __ZTS2S3
        .long   0
        .long   1
        .long   __ZTI2S2
        .long   -3069
        .globl __ZTS2S3
        .weak_definition __ZTS2S3
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S3:
        .ascii "2S3\0"
        .globl __ZTI2S2
        .weak_definition __ZTI2S2
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S2:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S2
        .globl __ZTS2S2
        .weak_definition __ZTS2S2
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S2:
        .ascii "2S2\0"
        .text
__Z41__static_initialization_and_destruction_0ii:
LFB26:
        pushl   %ebp
LCFI32:
        movl    %esp, %ebp
LCFI33:
        subl    $8, %esp
        call    ___x86.get_pc_thunk.ax
L11$pb:
        cmpl    $1, 8(%ebp)
        jne     L14
        cmpl    $65535, 12(%ebp)
        jne     L14
        subl    $12, %esp
        leal    _s8-L11$pb(%eax), %eax
        pushl   %eax
        call    __ZN2S8C1Ev
        addl    $16, %esp
L14:
        nop
        leave
LCFI34:
        ret
LFE26:
        .globl __ZTI2S7
        .weak_definition __ZTI2S7
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S7:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S7
        .globl __ZTS2S7
        .weak_definition __ZTS2S7
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S7:
        .ascii "2S7\0"
        .globl __ZTI2S1
        .weak_definition __ZTI2S1
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S1:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S1
        .globl __ZTS2S1
        .weak_definition __ZTS2S1
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S1:
        .ascii "2S1\0"
        .globl __ZTI2S6
        .weak_definition __ZTI2S6
        .section __DATA,__const_coal,coalesced
        .align 2
__ZTI2S6:
        .long   __ZTVN10__cxxabiv117__class_type_infoE+8
        .long   __ZTS2S6
        .globl __ZTS2S6
        .weak_definition __ZTS2S6
        .section __TEXT,__const_coal,coalesced
        .align 2
__ZTS2S6:
        .ascii "2S6\0"
        .text
__GLOBAL__sub_I_empty7.C:
LFB27:
        pushl   %ebp
LCFI35:
        movl    %esp, %ebp
LCFI36:
        subl    $8, %esp
        call    ___x86.get_pc_thunk.ax
L12$pb:
        subl    $8, %esp
        pushl   $65535
        pushl   $1
        call    __Z41__static_initialization_and_destruction_0ii
        addl    $16, %esp
        leave
LCFI37:
        ret
LFE27:
        .section __TEXT,__textcoal_nt,coalesced,pure_instructions
        .weak_definition        ___x86.get_pc_thunk.ax
        .private_extern ___x86.get_pc_thunk.ax
___x86.get_pc_thunk.ax:
LFB28:
        movl    (%esp), %eax
        ret
LFE28:
        .weak_definition        ___x86.get_pc_thunk.bx
        .private_extern ___x86.get_pc_thunk.bx
___x86.get_pc_thunk.bx:
LFB29:
        movl    (%esp), %ebx
        ret
LFE29:
        .section
__TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
        .set L$set$0,LECIE1-LSCIE1
        .long L$set$0
LSCIE1:
        .long   0
        .byte   0x1
        .ascii "zR\0"
        .byte   0x1
        .byte   0x7c
        .byte   0x8
        .byte   0x1
        .byte   0x10
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .byte   0x88
        .byte   0x1
        .align 2
LECIE1:
LSFDE1:
        .set L$set$1,LEFDE1-LASFDE1
        .long L$set$1
LASFDE1:
        .long   LASFDE1-EH_frame1
        .long   LFB0-.
        .set L$set$2,LFE0-LFB0
        .long L$set$2
        .byte   0
        .byte   0x4
        .set L$set$3,LCFI0-LFB0
        .long L$set$3
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$4,LCFI1-LCFI0
        .long L$set$4
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$5,LCFI2-LCFI1
        .long L$set$5
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE1:
LSFDE3:
        .set L$set$6,LEFDE3-LASFDE3
        .long L$set$6
LASFDE3:
        .long   LASFDE3-EH_frame1
        .long   LFB3-.
        .set L$set$7,LFE3-LFB3
        .long L$set$7
        .byte   0
        .byte   0x4
        .set L$set$8,LCFI3-LFB3
        .long L$set$8
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$9,LCFI4-LCFI3
        .long L$set$9
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$10,LCFI5-LCFI4
        .long L$set$10
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE3:
LSFDE5:
        .set L$set$11,LEFDE5-LASFDE5
        .long L$set$11
LASFDE5:
        .long   LASFDE5-EH_frame1
        .long   LFB6-.
        .set L$set$12,LFE6-LFB6
        .long L$set$12
        .byte   0
        .byte   0x4
        .set L$set$13,LCFI6-LFB6
        .long L$set$13
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$14,LCFI7-LCFI6
        .long L$set$14
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$15,LCFI8-LCFI7
        .long L$set$15
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE5:
LSFDE7:
        .set L$set$16,LEFDE7-LASFDE7
        .long L$set$16
LASFDE7:
        .long   LASFDE7-EH_frame1
        .long   LFB11-.
        .set L$set$17,LFE11-LFB11
        .long L$set$17
        .byte   0
        .byte   0x4
        .set L$set$18,LCFI9-LFB11
        .long L$set$18
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$19,LCFI10-LCFI9
        .long L$set$19
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$20,LCFI11-LCFI10
        .long L$set$20
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE7:
LSFDE9:
        .set L$set$21,LEFDE9-LASFDE9
        .long L$set$21
LASFDE9:
        .long   LASFDE9-EH_frame1
        .long   LFB14-.
        .set L$set$22,LFE14-LFB14
        .long L$set$22
        .byte   0
        .byte   0x4
        .set L$set$23,LCFI12-LFB14
        .long L$set$23
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$24,LCFI13-LCFI12
        .long L$set$24
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$25,LCFI14-LCFI13
        .long L$set$25
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE9:
LSFDE11:
        .set L$set$26,LEFDE11-LASFDE11
        .long L$set$26
LASFDE11:
        .long   LASFDE11-EH_frame1
        .long   LFB17-.
        .set L$set$27,LFE17-LFB17
        .long L$set$27
        .byte   0
        .byte   0x4
        .set L$set$28,LCFI15-LFB17
        .long L$set$28
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$29,LCFI16-LCFI15
        .long L$set$29
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$30,LCFI17-LCFI16
        .long L$set$30
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE11:
LSFDE13:
        .set L$set$31,LEFDE13-LASFDE13
        .long L$set$31
LASFDE13:
        .long   LASFDE13-EH_frame1
        .long   LFB20-.
        .set L$set$32,LFE20-LFB20
        .long L$set$32
        .byte   0
        .byte   0x4
        .set L$set$33,LCFI18-LFB20
        .long L$set$33
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$34,LCFI19-LCFI18
        .long L$set$34
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$35,LCFI20-LCFI19
        .long L$set$35
        .byte   0x83
        .byte   0x3
        .byte   0x4
        .set L$set$36,LCFI21-LCFI20
        .long L$set$36
        .byte   0xc4
        .byte   0xc3
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE13:
LSFDE15:
        .set L$set$37,LEFDE15-LASFDE15
        .long L$set$37
LASFDE15:
        .long   LASFDE15-EH_frame1
        .long   LFB21-.
        .set L$set$38,LFE21-LFB21
        .long L$set$38
        .byte   0
        .byte   0x4
        .set L$set$39,LCFI22-LFB21
        .long L$set$39
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$40,LCFI23-LCFI22
        .long L$set$40
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$41,LCFI24-LCFI23
        .long L$set$41
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE15:
LSFDE17:
        .set L$set$42,LEFDE17-LASFDE17
        .long L$set$42
LASFDE17:
        .long   LASFDE17-EH_frame1
        .long   LFB24-.
        .set L$set$43,LFE24-LFB24
        .long L$set$43
        .byte   0
        .byte   0x4
        .set L$set$44,LCFI25-LFB24
        .long L$set$44
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$45,LCFI26-LCFI25
        .long L$set$45
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$46,LCFI27-LCFI26
        .long L$set$46
        .byte   0x83
        .byte   0x3
        .byte   0x4
        .set L$set$47,LCFI28-LCFI27
        .long L$set$47
        .byte   0xc4
        .byte   0xc3
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE17:
LSFDE19:
        .set L$set$48,LEFDE19-LASFDE19
        .long L$set$48
LASFDE19:
        .long   LASFDE19-EH_frame1
        .long   LFB25-.
        .set L$set$49,LFE25-LFB25
        .long L$set$49
        .byte   0
        .byte   0x4
        .set L$set$50,LCFI29-LFB25
        .long L$set$50
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$51,LCFI30-LCFI29
        .long L$set$51
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$52,LCFI31-LCFI30
        .long L$set$52
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE19:
LSFDE21:
        .set L$set$53,LEFDE21-LASFDE21
        .long L$set$53
LASFDE21:
        .long   LASFDE21-EH_frame1
        .long   LFB26-.
        .set L$set$54,LFE26-LFB26
        .long L$set$54
        .byte   0
        .byte   0x4
        .set L$set$55,LCFI32-LFB26
        .long L$set$55
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$56,LCFI33-LCFI32
        .long L$set$56
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$57,LCFI34-LCFI33
        .long L$set$57
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE21:
LSFDE23:
        .set L$set$58,LEFDE23-LASFDE23
        .long L$set$58
LASFDE23:
        .long   LASFDE23-EH_frame1
        .long   LFB27-.
        .set L$set$59,LFE27-LFB27
        .long L$set$59
        .byte   0
        .byte   0x4
        .set L$set$60,LCFI35-LFB27
        .long L$set$60
        .byte   0xe
        .byte   0x8
        .byte   0x84
        .byte   0x2
        .byte   0x4
        .set L$set$61,LCFI36-LCFI35
        .long L$set$61
        .byte   0xd
        .byte   0x4
        .byte   0x4
        .set L$set$62,LCFI37-LCFI36
        .long L$set$62
        .byte   0xc4
        .byte   0xc
        .byte   0x5
        .byte   0x4
        .align 2
LEFDE23:
LSFDE25:
        .set L$set$63,LEFDE25-LASFDE25
        .long L$set$63
LASFDE25:
        .long   LASFDE25-EH_frame1
        .long   LFB28-.
        .set L$set$64,LFE28-LFB28
        .long L$set$64
        .byte   0
        .align 2
LEFDE25:
LSFDE27:
        .set L$set$65,LEFDE27-LASFDE27
        .long L$set$65
LASFDE27:
        .long   LASFDE27-EH_frame1
        .long   LFB29-.
        .set L$set$66,LFE29-LFB29
        .long L$set$66
        .byte   0
        .align 2
LEFDE27:
        .mod_init_func
        .align 2
        .long   __GLOBAL__sub_I_empty7.C
        .constructor
        .destructor
        .align 1
        .subsections_via_symbols



On Sat, Feb 7, 2015 at 10:11 AM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
> H.J,,
>     Unfortunately, the answer is yes. This patch still introduces
> regressions in the g++ test suite.l These are all some form of...
>
> Executing on host:
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
>  -fno-diagnostics-show-caret -fdiagnostics-color=never  -nostdinc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
> -fmessage-length=0  -std=gnu++98 -fabi-version=0
> -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
>  -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
>  -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
>  -multiply_defined suppress -lm   -m32  -o ./empty7.exe    (timeout =
> 300)
> spawn -ignore SIGHUP
> /sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
> /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/g++.dg/abi/empty7.C
> -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include/x86_64-apple-darwin14.3.0
> -I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/include
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/libsupc++
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/include/backward
> -I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/libstdc++-v3/testsuite/util
> -fmessage-length=0 -std=gnu++98 -fabi-version=0
> -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
> -B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
> -L/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin14.3.0/i386/libstdc++-v3/src/.libs
> -multiply_defined suppress -lm -m32 -o ./empty7.exe^M
> ld: warning: direct access in S2::S2()    to global weak symbol vtable
> for S2 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S8::S8()    to global weak symbol vtable
> for S8 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> output is:
> ld: warning: direct access in S2::S2()    to global weak symbol vtable
> for S2 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol vtable
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S5::S5()    to global weak symbol VTT
> for S5 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
> ld: warning: direct access in S8::S8()    to global weak symbol vtable
> for S8 means the weak symbol cannot be overridden at runtime. This was
> likely caused by different translation units being compiled with
> different visibility settings.^M
>
>
> FAIL: g++.dg/abi/empty7.C  -std=gnu++98 (test for excess errors)
>
> Darwin has really twitchy support weak symbol support so any major
> rewrite will definitely be stage 1 material and likely require us to
> contact the darwin linker developer at Apple for a consultation on the
> meaning of these linker warnings.
>             Jack
>
>
>
> On Sat, Feb 7, 2015 at 7:27 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Sat, Feb 07, 2015 at 03:28:38AM -0500, Jack Howarth wrote:
>>> H.J.,
>>>      The new patch bootstraps okay on x86_64-apple-darwin14 but I
>>
>> Does it cause any regressions on x86_64-apple-darwin14?
>>
>>> discovered that you need a small adjustment in the deja-gnu
>>> statements...
>>>
>>>  --- /Users/howarth/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>> 2015-02-06 21:45:04.000000000 -0500
>>> +++ /sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150206/gcc/testsuite/gcc.dg/visibility-22.c
>>> 2015-02-07 03:24:42.000000000 -0500
>>> @@ -8,9 +8,9 @@
>>>  /* For kernel modules and static RTPs, the loader treats undefined weak
>>>     symbols in the same way as undefined strong symbols.  The test
>>>     therefore fails to load, so skip it.  */
>>> +/* { dg-options "-fPIC" { target fpic } } */
>>>  /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target
>>> *-*-darwin* } } */
>>>  /* { dg-additional-options "-Wl,-flat_namespace" { target
>>> *-*-darwin[89]* } } */
>>> -/* { dg-options "-fPIC" { target fpic } } */
>>>
>>>  extern void foo () __attribute__((weak,visibility("hidden")));
>>>  int
>>>
>>> If you don't define a dg-options line first, the dg-additional-options
>>> lines have no effect.
>>>                  Jack
>>
>> Here is the updated patch.
>>
>> H.J.
>> ---
>> From 8e61705db8177d41fac45dbeffa4faf6163d4c94 Mon Sep 17 00:00:00 2001
>> From: "H.J. Lu" <hjl.tools@gmail.com>
>> Date: Thu, 5 Feb 2015 14:28:58 -0800
>> Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC
>>
>> If a hidden weak symbol isn't defined in the TU, we can't assume it will
>> be defined in another TU at link time.  It makes a difference in code
>> generation when compiling for PIC. If we assume that a hidden weak
>> undefined symbol is local, the address checking may be optimized out and
>> leads to the wrong code.  This means that a symbol with user specified
>> visibility is local only if it is locally resolved or defined, not weak
>> or not compiling for PIC.  When symbol visibility is specified in the
>> source, we should always output symbol visibility even if symbol isn't
>> local to the TU.
>>
>> If a global data symbol is defined in the TU, it is always local to the
>> executable, regardless if it is a common symbol or not.  If we aren't
>> compiling for shared library, locally defined global data symbol binds
>> locally.
>>
>> gcc/
>>
>>         PR rtl-optimization/32219
>>         * cgraphunit.c (varpool_node::finalize_decl): Set definition
>>         first before calling notice_global_symbol so that it is
>>         available to notice_global_symbol.
>>         * varasm.c (default_binds_local_p_1): Resolve defined data
>>         symbol locally if not building shared library.  Resolve symbol
>>         with user specified visibility locally only if it is locally
>>         resolved or defined, not weak or not compiling for PIC.
>>         (default_elf_asm_output_external): Always output visibility
>>         specified in the source.
>>         * config/darwin-protos.h (darwin_output_external): New.
>>         * config/darwin.c (darwin_output_external): Likewise.
>>         * config/darwin.h (ASM_OUTPUT_EXTERNAL): Likewise.
>>
>> gcc/testsuite/
>>
>>         PR rtl-optimization/32219
>>         * gcc.dg/visibility-22.c: New test.
>>         * gcc.dg/visibility-23.c: Likewise.
>>         * gcc.target/i386/pr32219-1.c: Likewise.
>>         * gcc.target/i386/pr32219-2.c: Likewise.
>>         * gcc.target/i386/pr32219-3.c: Likewise.
>>         * gcc.target/i386/pr32219-4.c: Likewise.
>>         * gcc.target/i386/pr32219-5.c: Likewise.
>>         * gcc.target/i386/pr32219-6.c: Likewise.
>>         * gcc.target/i386/pr32219-7.c: Likewise.
>>         * gcc.target/i386/pr32219-8.c: Likewise.
>>         * gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
>>         of GOT relocation.
>> ---
>>  gcc/cgraphunit.c                          |  4 +++-
>>  gcc/config/darwin-protos.h                |  1 +
>>  gcc/config/darwin.c                       | 15 +++++++++++++
>>  gcc/config/darwin.h                       |  9 ++++++++
>>  gcc/testsuite/gcc.dg/visibility-22.c      | 22 +++++++++++++++++++
>>  gcc/testsuite/gcc.dg/visibility-23.c      | 14 +++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++
>>  gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
>>  gcc/varasm.c                              | 35 ++++++++++++++++++-------------
>>  16 files changed, 217 insertions(+), 17 deletions(-)
>>  create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
>>  create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
>>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c
>>
>> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
>> index 35b244e..71367a3 100644
>> --- a/gcc/cgraphunit.c
>> +++ b/gcc/cgraphunit.c
>> @@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
>>
>>    if (node->definition)
>>      return;
>> -  notice_global_symbol (decl);
>> +  /* Set definition first before calling notice_global_symbol so that
>> +     it is available to notice_global_symbol.  */
>>    node->definition = true;
>> +  notice_global_symbol (decl);
>>    if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
>>        /* Traditionally we do not eliminate static variables when not
>>          optimizing and when not doing toplevel reoder.  */
>> diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
>> index 249b9c1..10a77fc 100644
>> --- a/gcc/config/darwin-protos.h
>> +++ b/gcc/config/darwin-protos.h
>> @@ -89,6 +89,7 @@ extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
>>  extern void machopic_output_stub (FILE *, const char *, const char *);
>>  extern void darwin_globalize_label (FILE *, const char *);
>>  extern void darwin_assemble_visibility (tree, int);
>> +extern void darwin_output_external (FILE *, tree, const char *name);
>>
>>  extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
>>                                            const char *);
>> diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
>> index 40804b8..5025ef7 100644
>> --- a/gcc/config/darwin.c
>> +++ b/gcc/config/darwin.c
>> @@ -2762,6 +2762,21 @@ darwin_assemble_visibility (tree decl, int vis)
>>              "not supported in this configuration; ignored");
>>  }
>>
>> +/* Emit text to declare externally defined symbols.  Used to support
>> +   undefined hidden visibility with Darwin's private extern feature.  */
>> +
>> +void
>> +darwin_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl,
>> +                       const char *name ATTRIBUTE_UNUSED)
>> +{
>> +  /* We output the name if and only if TREE_SYMBOL_REFERENCED is set and
>> +     visibility is specified in the source in order to avoid putting out
>> +     names that are never really used.  */
>> +  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
>> +      && DECL_VISIBILITY_SPECIFIED (decl))
>> +    darwin_assemble_visibility (decl, DECL_VISIBILITY (decl));
>> +}
>> +
>>  /* vec used by darwin_asm_dwarf_section.
>>     Maybe a hash tab would be better here - but the intention is that this is
>>     a very short list (fewer than 16 items) and each entry should (ideally,
>> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
>> index b61dbb5..c9a1b34 100644
>> --- a/gcc/config/darwin.h
>> +++ b/gcc/config/darwin.h
>> @@ -700,6 +700,15 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
>>  #undef TARGET_ASM_ASSEMBLE_VISIBILITY
>>  #define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
>>
>> +/* A C statement (sans semicolon) to output to the stdio stream STREAM
>> +   any text necessary for declaring the name of an external symbol
>> +   named NAME which is referenced in this compilation but not defined.
>> +   Used to support undefined hidden visibility with Darwin's private
>> +   extern feature.  */
>> +
>> +#undef ASM_OUTPUT_EXTERNAL
>> +#define ASM_OUTPUT_EXTERNAL darwin_output_external
>> +
>>  /* Extra attributes for Darwin.  */
>>  #define SUBTARGET_ATTRIBUTE_TABLE                                           \
>>    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
>> diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
>> new file mode 100644
>> index 0000000..a118a6e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/visibility-22.c
>> @@ -0,0 +1,22 @@
>> +/* PR target/32219 */
>> +/* { dg-do run } */
>> +/* { dg-require-visibility "" } */
>> +/* { dg-options "-O2 -fPIC" { target fpic } } */
>> +/* This test requires support for undefined weak symbols.  This support
>> +   is not available on hppa*-*-hpux*.  The test is skipped rather than
>> +   xfailed to suppress the warning that would otherwise arise.  */
>> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }  */
>> +/* For kernel modules and static RTPs, the loader treats undefined weak
>> +   symbols in the same way as undefined strong symbols.  The test
>> +   therefore fails to load, so skip it.  */
>> +/* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
>> +/* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
>> +
>> +extern void foo () __attribute__((weak,visibility("hidden")));
>> +int
>> +main()
>> +{
>> +  if (foo)
>> +    foo ();
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
>> new file mode 100644
>> index 0000000..347578e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/visibility-23.c
>> @@ -0,0 +1,14 @@
>> +/* PR target/32219 */
>> +/* { dg-do compile } */
>> +/* { dg-require-visibility "" } */
>> +/* { dg-final { scan-hidden "foo" } } */
>> +/* { dg-options "-O2 -fPIC" { target fpic } } */
>> +
>> +extern void foo () __attribute__((weak,visibility("hidden")));
>> +int
>> +main()
>> +{
>> +  if (foo)
>> +    foo ();
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
>> new file mode 100644
>> index 0000000..5bd80a0
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Common symbol with -fpie.  */
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
>> new file mode 100644
>> index 0000000..0cf2eb5
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Common symbol with -fpic.  */
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
>> new file mode 100644
>> index 0000000..911f2a5
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Weak common symbol with -fpie.  */
>> +__attribute__((weak))
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
>> new file mode 100644
>> index 0000000..3d43439
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Weak common symbol with -fpic.  */
>> +__attribute__((weak))
>> +int xxx;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
>> new file mode 100644
>> index 0000000..ee7442e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Initialized symbol with -fpie.  */
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
>> new file mode 100644
>> index 0000000..f261433
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Initialized symbol with -fpic.  */
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
>> new file mode 100644
>> index 0000000..12aaf72
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpie" } */
>> +
>> +/* Weak initialized symbol with -fpie.  */
>> +__attribute__((weak))
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
>> new file mode 100644
>> index 0000000..2e4fba0
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile { target *-*-linux* } } */
>> +/* { dg-options "-O2 -fpic" } */
>> +
>> +/* Weak initialized symbol with -fpic.  */
>> +__attribute__((weak))
>> +int xxx = -1;
>> +
>> +int
>> +foo ()
>> +{
>> +  return xxx;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
>> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
>> diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
>> index 33f5b5d..32969fc 100644
>> --- a/gcc/testsuite/gcc.target/i386/pr64317.c
>> +++ b/gcc/testsuite/gcc.target/i386/pr64317.c
>> @@ -1,7 +1,7 @@
>>  /* { dg-do compile { target { *-*-linux* && ia32 } } } */
>>  /* { dg-options "-O2 -fpie" } */
>>  /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
>> -/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
>> +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
>>  /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
>>  long c;
>>
>> diff --git a/gcc/varasm.c b/gcc/varasm.c
>> index eb65b1f..f7c13af 100644
>> --- a/gcc/varasm.c
>> +++ b/gcc/varasm.c
>> @@ -6826,11 +6826,17 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>>      {
>>        varpool_node *vnode = varpool_node::get (exp);
>> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
>> -       resolved_locally = true;
>> -      if (vnode
>> -         && resolution_to_local_definition_p (vnode->resolution))
>> -       resolved_to_local_def = true;
>> +      /* If not building shared library, common or initialized symbols
>> +        are also resolved locally, regardless they are weak or not.  */
>> +      if (vnode)
>> +       {
>> +         if ((!shlib && vnode->definition)
>> +             || vnode->in_other_partition
>> +             || resolution_local_p (vnode->resolution))
>> +           resolved_locally = true;
>> +         if (resolution_to_local_definition_p (vnode->resolution))
>> +           resolved_to_local_def = true;
>> +       }
>>      }
>>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>>      {
>> @@ -6859,9 +6865,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>    else if (! TREE_PUBLIC (exp))
>>      local_p = true;
>>    /* A variable is local if the user has said explicitly that it will
>> -     be.  */
>> +     be and it is resolved or defined locally, not compiling for PIC or
>> +     not weak.  */
>>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>>             || resolved_to_local_def)
>> +          && (resolved_locally
>> +              || !flag_pic
>> +              || !DECL_EXTERNAL (exp)
>> +              || !DECL_WEAK (exp))
>>            && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>>      local_p = true;
>>    /* Variables defined outside this object might not be local.  */
>> @@ -6880,13 +6891,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>       symbols resolved from other modules.  */
>>    else if (shlib)
>>      local_p = false;
>> -  /* Uninitialized COMMON variable may be unified with symbols
>> -     resolved from other modules.  */
>> -  else if (DECL_COMMON (exp)
>> -          && !resolved_locally
>> -          && (DECL_INITIAL (exp) == NULL
>> -              || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
>> -    local_p = false;
>>    /* Otherwise we're left with initialized (or non-common) global data
>>       which is of necessity defined locally.  */
>>    else
>> @@ -7445,9 +7449,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>>  {
>>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>>       set in order to avoid putting out names that are never really
>> -     used. */
>> +     used.   Always output visibility specified in the source.  */
>>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
>> -      && targetm.binds_local_p (decl))
>> +      && (DECL_VISIBILITY_SPECIFIED (decl)
>> +         || targetm.binds_local_p (decl)))
>>      maybe_assemble_visibility (decl);
>>  }
>>
>> --
>> 2.1.0
>>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07 15:11             ` Jack Howarth
  2015-02-07 15:25               ` Jack Howarth
@ 2015-02-07 15:56               ` H.J. Lu
  2015-02-07 16:45                 ` H.J. Lu
  2015-02-07 19:37                 ` [PATCH] PR rtl-optimization/32219: optimizer causes " Jack Howarth
  1 sibling, 2 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-07 15:56 UTC (permalink / raw)
  To: Jack Howarth; +Cc: GCC Patches, Mike Stump, Iain Sandoe

On Sat, Feb 07, 2015 at 10:11:01AM -0500, Jack Howarth wrote:
> H.J,,
>     Unfortunately, the answer is yes. This patch still introduces
> regressions in the g++ test suite.l These are all some form of...
> 

It looks like Darwin depends on the old behavior of
default_binds_local_p_1.  Please try this patch.


H.J.

From 2df2188c97760ed10a85bff3dfef8198e41862f2 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 5 Feb 2015 14:28:58 -0800
Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC

If a hidden weak symbol isn't defined in the TU, we can't assume it will
be defined in another TU at link time.  It makes a difference in code
generation when compiling for PIC. If we assume that a hidden weak
undefined symbol is local, the address checking may be optimized out and
leads to the wrong code.  This means that a symbol with user specified
visibility is local only if it is locally resolved or defined, not weak
or not compiling for PIC.  When symbol visibility is specified in the
source, we should always output symbol visibility even if symbol isn't
local to the TU.

If a global data symbol is defined in the TU, it is always local to the
executable, regardless if it is a common symbol or not.  If we aren't
compiling for shared library, locally defined global data symbol binds
locally.

Since some targets call default_binds_local_p_1 directly and depend on
the old behavior of default_binds_local_p_1.  This patch copies
default_binds_local_p_1 to default_binds_local_p_2 and changes the
behavior of default_binds_local_p by calling default_binds_local_p_2
instead of default_binds_local_p_1.

gcc/

	PR rtl-optimization/32219
	* cgraphunit.c (varpool_node::finalize_decl): Set definition
	first before calling notice_global_symbol so that it is
	available to notice_global_symbol.
	* varasm.c (default_binds_local_p_2): Copied from
	default_binds_local_p_1.  Resolve defined data symbol locally if
	not building shared library.  Resolve symbol with user specified
	visibility locally only if it is locally resolved or defined, not
	weak or not compiling for PIC.
	(default_binds_local_p): Replace default_binds_local_p_1 with
	default_binds_local_p_2.
	(default_elf_asm_output_external): Always output visibility
	specified in the source.

gcc/testsuite/

	PR rtl-optimization/32219
	* gcc.dg/visibility-22.c: New test.
	* gcc.dg/visibility-23.c: Likewise.
	* gcc.target/i386/pr32219-1.c: Likewise.
	* gcc.target/i386/pr32219-2.c: Likewise.
	* gcc.target/i386/pr32219-3.c: Likewise.
	* gcc.target/i386/pr32219-4.c: Likewise.
	* gcc.target/i386/pr32219-5.c: Likewise.
	* gcc.target/i386/pr32219-6.c: Likewise.
	* gcc.target/i386/pr32219-7.c: Likewise.
	* gcc.target/i386/pr32219-8.c: Likewise.
	* gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
	of GOT relocation.
---
 gcc/cgraphunit.c                          |  4 +-
 gcc/testsuite/gcc.dg/visibility-22.c      | 17 ++++++
 gcc/testsuite/gcc.dg/visibility-23.c      | 15 +++++
 gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++
 gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++
 gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 ++++++
 gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 ++++++
 gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++
 gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++
 gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 ++++++
 gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 ++++++
 gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
 gcc/varasm.c                              | 95 ++++++++++++++++++++++++++++++-
 13 files changed, 260 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
 create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 35b244e..71367a3 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
new file mode 100644
index 0000000..52f59be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-22.c
@@ -0,0 +1,17 @@
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* This test requires support for undefined weak symbols.  This support
+   is not available on hppa*-*-hpux*.  The test is skipped rather than
+   xfailed to suppress the warning that would otherwise arise.  */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
new file mode 100644
index 0000000..0fa9ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-23.c
@@ -0,0 +1,15 @@
+/* PR target/32219 */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "foo" } } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
new file mode 100644
index 0000000..5bd80a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Common symbol with -fpie.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
new file mode 100644
index 0000000..0cf2eb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
new file mode 100644
index 0000000..911f2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak common symbol with -fpie.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
new file mode 100644
index 0000000..3d43439
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
new file mode 100644
index 0000000..ee7442e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Initialized symbol with -fpie.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
new file mode 100644
index 0000000..f261433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
new file mode 100644
index 0000000..12aaf72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak initialized symbol with -fpie.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
new file mode 100644
index 0000000..2e4fba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 33f5b5d..32969fc 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { *-*-linux* && ia32 } } } */
 /* { dg-options "-O2 -fpie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index eb65b1f..b7ef575 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6802,13 +6802,101 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution)
 	  || resolution == LDPR_RESOLVED_EXEC);
 }
 
+static bool
+default_binds_local_p_2 (const_tree exp, int shlib)
+{
+  bool local_p;
+  bool resolved_locally = false;
+  bool resolved_to_local_def = false;
+
+  /* With resolution file in hands, take look into resolutions.
+     We can't just return true for resolved_locally symbols,
+     because dynamic linking might overwrite symbols
+     in shared libraries.  */
+  if (TREE_CODE (exp) == VAR_DECL && TREE_PUBLIC (exp)
+      && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
+    {
+      varpool_node *vnode = varpool_node::get (exp);
+      /* If not building shared library, common or initialized symbols
+	 are also resolved locally, regardless they are weak or not.  */
+      if (vnode)
+	{
+	  if ((!shlib && vnode->definition)
+	      || vnode->in_other_partition
+	      || resolution_local_p (vnode->resolution))
+	    resolved_locally = true;
+	  if (resolution_to_local_definition_p (vnode->resolution))
+	    resolved_to_local_def = true;
+	}
+    }
+  else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
+    {
+      struct cgraph_node *node = cgraph_node::get (exp);
+      if (node
+	  && (resolution_local_p (node->resolution) || node->in_other_partition))
+	resolved_locally = true;
+      if (node
+	  && resolution_to_local_definition_p (node->resolution))
+	resolved_to_local_def = true;
+    }
+
+  /* A non-decl is an entry in the constant pool.  */
+  if (!DECL_P (exp))
+    local_p = true;
+  /* Weakrefs may not bind locally, even though the weakref itself is always
+     static and therefore local.  Similarly, the resolver for ifunc functions
+     might resolve to a non-local function.
+     FIXME: We can resolve the weakref case more curefuly by looking at the
+     weakref alias.  */
+  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+	   || (TREE_CODE (exp) == FUNCTION_DECL
+	       && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
+    local_p = false;
+  /* Static variables are always local.  */
+  else if (! TREE_PUBLIC (exp))
+    local_p = true;
+  /* A variable is local if the user has said explicitly that it will
+     be and it is resolved or defined locally, not compiling for PIC or
+     not weak.  */
+  else if ((DECL_VISIBILITY_SPECIFIED (exp)
+	    || resolved_to_local_def)
+	   && (resolved_locally
+	       || !flag_pic
+	       || !DECL_EXTERNAL (exp)
+	       || !DECL_WEAK (exp))
+	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
+    local_p = true;
+  /* Variables defined outside this object might not be local.  */
+  else if (DECL_EXTERNAL (exp) && !resolved_locally)
+    local_p = false;
+  /* If defined in this object and visibility is not default, must be
+     local.  */
+  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
+    local_p = true;
+  /* Default visibility weak data can be overridden by a strong symbol
+     in another module and so are not local.  */
+  else if (DECL_WEAK (exp)
+	   && !resolved_locally)
+    local_p = false;
+  /* If PIC, then assume that any global name can be overridden by
+     symbols resolved from other modules.  */
+  else if (shlib)
+    local_p = false;
+  /* Otherwise we're left with initialized (or non-common) global data
+     which is of necessity defined locally.  */
+  else
+    local_p = true;
+
+  return local_p;
+}
+
 /* Assume ELF-ish defaults, since that's pretty much the most liberal
    wrt cross-module name binding.  */
 
 bool
 default_binds_local_p (const_tree exp)
 {
-  return default_binds_local_p_1 (exp, flag_shlib);
+  return default_binds_local_p_2 (exp, flag_shlib);
 }
 
 bool
@@ -7445,9 +7533,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.   Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07 15:56               ` H.J. Lu
@ 2015-02-07 16:45                 ` H.J. Lu
  2015-02-08 18:24                   ` Jack Howarth
  2015-02-10 21:19                   ` Richard Henderson
  2015-02-07 19:37                 ` [PATCH] PR rtl-optimization/32219: optimizer causes " Jack Howarth
  1 sibling, 2 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-07 16:45 UTC (permalink / raw)
  To: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe

On Sat, Feb 07, 2015 at 07:56:06AM -0800, H.J. Lu wrote:
> On Sat, Feb 07, 2015 at 10:11:01AM -0500, Jack Howarth wrote:
> > H.J,,
> >     Unfortunately, the answer is yes. This patch still introduces
> > regressions in the g++ test suite.l These are all some form of...
> > 
> 
> It looks like Darwin depends on the old behavior of
> default_binds_local_p_1.  Please try this patch.
> 

Here is an updated patch.


H.J.
From d010cd1ddf866f8e10fe7ad2cf483b5a872bc6ea Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 5 Feb 2015 14:28:58 -0800
Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC

If a hidden weak symbol isn't defined in the TU, we can't assume it will
be defined in another TU at link time.  It makes a difference in code
generation when compiling for PIC. If we assume that a hidden weak
undefined symbol is local, the address checking may be optimized out and
leads to the wrong code.  This means that a symbol with user specified
visibility is local only if it is locally resolved or defined, not weak
or not compiling for PIC.  When symbol visibility is specified in the
source, we should always output symbol visibility even if symbol isn't
local to the TU.

If a global data symbol is defined in the TU, it is always local to the
executable, regardless if it is a common symbol or not.  If we aren't
compiling for shared library, locally defined global data symbol binds
locally.

Since some targets call default_binds_local_p_1 directly and depend on
the old behavior of default_binds_local_p_1.  This patch renames
default_binds_local_p_1 to default_binds_local_p_2 and implements the
new behavior in default_binds_local_p_2 controlled by a variable.
The old behavior remains with default_binds_local_p_1.

gcc/

	PR rtl-optimization/32219
	* cgraphunit.c (varpool_node::finalize_decl): Set definition
	first before calling notice_global_symbol so that it is
	available to notice_global_symbol.
	* varasm.c (default_binds_local_p_1): Renamed to ...
	(default_binds_local_p_2): This.  Resolve defined data symbol
	locally if not building shared library.  Resolve symbol with
	user specified visibility locally only if it is locally resolved
	or defined, not weak or not compiling for PIC.
	(default_binds_local_p): Replace default_binds_local_p_1 with
	default_binds_local_p_2.
	(default_binds_local_p_1): Call default_binds_local_p_2.
	(default_elf_asm_output_external): Always output visibility
	specified in the source.

gcc/testsuite/

	PR rtl-optimization/32219
	* gcc.dg/visibility-22.c: New test.
	* gcc.dg/visibility-23.c: Likewise.
	* gcc.target/i386/pr32219-1.c: Likewise.
	* gcc.target/i386/pr32219-2.c: Likewise.
	* gcc.target/i386/pr32219-3.c: Likewise.
	* gcc.target/i386/pr32219-4.c: Likewise.
	* gcc.target/i386/pr32219-5.c: Likewise.
	* gcc.target/i386/pr32219-6.c: Likewise.
	* gcc.target/i386/pr32219-7.c: Likewise.
	* gcc.target/i386/pr32219-8.c: Likewise.
	* gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
	of GOT relocation.
---
 gcc/cgraphunit.c                          |  4 +-
 gcc/testsuite/gcc.dg/visibility-22.c      | 17 +++++++++
 gcc/testsuite/gcc.dg/visibility-23.c      | 15 ++++++++
 gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++
 gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++
 gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++
 gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++
 gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++
 gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++
 gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++
 gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++
 gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
 gcc/varasm.c                              | 61 +++++++++++++++++++++----------
 13 files changed, 209 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
 create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 35b244e..71367a3 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
new file mode 100644
index 0000000..52f59be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-22.c
@@ -0,0 +1,17 @@
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* This test requires support for undefined weak symbols.  This support
+   is not available on hppa*-*-hpux*.  The test is skipped rather than
+   xfailed to suppress the warning that would otherwise arise.  */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
new file mode 100644
index 0000000..0fa9ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-23.c
@@ -0,0 +1,15 @@
+/* PR target/32219 */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "foo" } } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
new file mode 100644
index 0000000..5bd80a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Common symbol with -fpie.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
new file mode 100644
index 0000000..0cf2eb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
new file mode 100644
index 0000000..911f2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak common symbol with -fpie.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
new file mode 100644
index 0000000..3d43439
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
new file mode 100644
index 0000000..ee7442e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Initialized symbol with -fpie.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
new file mode 100644
index 0000000..f261433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
new file mode 100644
index 0000000..12aaf72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak initialized symbol with -fpie.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
new file mode 100644
index 0000000..2e4fba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 33f5b5d..32969fc 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { *-*-linux* && ia32 } } } */
 /* { dg-options "-O2 -fpie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index eb65b1f..e4bc2c1 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6802,17 +6802,8 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution)
 	  || resolution == LDPR_RESOLVED_EXEC);
 }
 
-/* Assume ELF-ish defaults, since that's pretty much the most liberal
-   wrt cross-module name binding.  */
-
-bool
-default_binds_local_p (const_tree exp)
-{
-  return default_binds_local_p_1 (exp, flag_shlib);
-}
-
-bool
-default_binds_local_p_1 (const_tree exp, int shlib)
+static bool
+default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
 {
   bool local_p;
   bool resolved_locally = false;
@@ -6826,11 +6817,18 @@ default_binds_local_p_1 (const_tree exp, int shlib)
       && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
     {
       varpool_node *vnode = varpool_node::get (exp);
-      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
-	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->resolution))
-	resolved_to_local_def = true;
+      /* If not building shared library, common or initialized symbols
+	 are also resolved locally, regardless they are weak or not if
+	 weak_dominate is true.  */
+      if (vnode)
+	{
+	  if ((weak_dominate && !shlib && vnode->definition)
+	      || vnode->in_other_partition
+	      || resolution_local_p (vnode->resolution))
+	    resolved_locally = true;
+	  if (resolution_to_local_definition_p (vnode->resolution))
+	    resolved_to_local_def = true;
+	}
     }
   else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
     {
@@ -6859,9 +6857,15 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   else if (! TREE_PUBLIC (exp))
     local_p = true;
   /* A variable is local if the user has said explicitly that it will
-     be.  */
+     be and it is resolved or defined locally, not compiling for PIC,
+     not weak or weak_dominate is false.  */
   else if ((DECL_VISIBILITY_SPECIFIED (exp)
 	    || resolved_to_local_def)
+	   && (!weak_dominate
+	       || resolved_locally
+	       || !flag_pic
+	       || !DECL_EXTERNAL (exp)
+	       || !DECL_WEAK (exp))
 	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     local_p = true;
   /* Variables defined outside this object might not be local.  */
@@ -6881,8 +6885,9 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   else if (shlib)
     local_p = false;
   /* Uninitialized COMMON variable may be unified with symbols
-     resolved from other modules.  */
+     resolved from other modules unless weak_dominate is true.  */
   else if (DECL_COMMON (exp)
+	   && !weak_dominate
 	   && !resolved_locally
 	   && (DECL_INITIAL (exp) == NULL
 	       || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
@@ -6895,6 +6900,21 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   return local_p;
 }
 
+/* Assume ELF-ish defaults, since that's pretty much the most liberal
+   wrt cross-module name binding.  */
+
+bool
+default_binds_local_p (const_tree exp)
+{
+  return default_binds_local_p_2 (exp, flag_shlib != 0, true);
+}
+
+bool
+default_binds_local_p_1 (const_tree exp, int shlib)
+{
+  return default_binds_local_p_2 (exp, shlib != 0, false);
+}
+
 /* Return true when references to DECL must bind to current definition in
    final executable.
 
@@ -7445,9 +7465,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.   Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07 15:56               ` H.J. Lu
  2015-02-07 16:45                 ` H.J. Lu
@ 2015-02-07 19:37                 ` Jack Howarth
  1 sibling, 0 replies; 53+ messages in thread
From: Jack Howarth @ 2015-02-07 19:37 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches, Mike Stump, Iain Sandoe

H.J.,
      This one bootstrap and appears to give clean c++ test suite
results so far on x86_64-apple-darwin14. I am stopping the regression
testing to try the updated patch you sent later.
                       Jack

On Sat, Feb 7, 2015 at 10:56 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sat, Feb 07, 2015 at 10:11:01AM -0500, Jack Howarth wrote:
>> H.J,,
>>     Unfortunately, the answer is yes. This patch still introduces
>> regressions in the g++ test suite.l These are all some form of...
>>
>
> It looks like Darwin depends on the old behavior of
> default_binds_local_p_1.  Please try this patch.
>
>
> H.J.
>
> From 2df2188c97760ed10a85bff3dfef8198e41862f2 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 5 Feb 2015 14:28:58 -0800
> Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC
>
> If a hidden weak symbol isn't defined in the TU, we can't assume it will
> be defined in another TU at link time.  It makes a difference in code
> generation when compiling for PIC. If we assume that a hidden weak
> undefined symbol is local, the address checking may be optimized out and
> leads to the wrong code.  This means that a symbol with user specified
> visibility is local only if it is locally resolved or defined, not weak
> or not compiling for PIC.  When symbol visibility is specified in the
> source, we should always output symbol visibility even if symbol isn't
> local to the TU.
>
> If a global data symbol is defined in the TU, it is always local to the
> executable, regardless if it is a common symbol or not.  If we aren't
> compiling for shared library, locally defined global data symbol binds
> locally.
>
> Since some targets call default_binds_local_p_1 directly and depend on
> the old behavior of default_binds_local_p_1.  This patch copies
> default_binds_local_p_1 to default_binds_local_p_2 and changes the
> behavior of default_binds_local_p by calling default_binds_local_p_2
> instead of default_binds_local_p_1.
>
> gcc/
>
>         PR rtl-optimization/32219
>         * cgraphunit.c (varpool_node::finalize_decl): Set definition
>         first before calling notice_global_symbol so that it is
>         available to notice_global_symbol.
>         * varasm.c (default_binds_local_p_2): Copied from
>         default_binds_local_p_1.  Resolve defined data symbol locally if
>         not building shared library.  Resolve symbol with user specified
>         visibility locally only if it is locally resolved or defined, not
>         weak or not compiling for PIC.
>         (default_binds_local_p): Replace default_binds_local_p_1 with
>         default_binds_local_p_2.
>         (default_elf_asm_output_external): Always output visibility
>         specified in the source.
>
> gcc/testsuite/
>
>         PR rtl-optimization/32219
>         * gcc.dg/visibility-22.c: New test.
>         * gcc.dg/visibility-23.c: Likewise.
>         * gcc.target/i386/pr32219-1.c: Likewise.
>         * gcc.target/i386/pr32219-2.c: Likewise.
>         * gcc.target/i386/pr32219-3.c: Likewise.
>         * gcc.target/i386/pr32219-4.c: Likewise.
>         * gcc.target/i386/pr32219-5.c: Likewise.
>         * gcc.target/i386/pr32219-6.c: Likewise.
>         * gcc.target/i386/pr32219-7.c: Likewise.
>         * gcc.target/i386/pr32219-8.c: Likewise.
>         * gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
>         of GOT relocation.
> ---
>  gcc/cgraphunit.c                          |  4 +-
>  gcc/testsuite/gcc.dg/visibility-22.c      | 17 ++++++
>  gcc/testsuite/gcc.dg/visibility-23.c      | 15 +++++
>  gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++
>  gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++
>  gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 ++++++
>  gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 ++++++
>  gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++
>  gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++
>  gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 ++++++
>  gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 ++++++
>  gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
>  gcc/varasm.c                              | 95 ++++++++++++++++++++++++++++++-
>  13 files changed, 260 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c
>
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 35b244e..71367a3 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
>
>    if (node->definition)
>      return;
> -  notice_global_symbol (decl);
> +  /* Set definition first before calling notice_global_symbol so that
> +     it is available to notice_global_symbol.  */
>    node->definition = true;
> +  notice_global_symbol (decl);
>    if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
>        /* Traditionally we do not eliminate static variables when not
>          optimizing and when not doing toplevel reoder.  */
> diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
> new file mode 100644
> index 0000000..52f59be
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-22.c
> @@ -0,0 +1,17 @@
> +/* PR target/32219 */
> +/* { dg-do run } */
> +/* { dg-require-visibility "" } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +/* This test requires support for undefined weak symbols.  This support
> +   is not available on hppa*-*-hpux*.  The test is skipped rather than
> +   xfailed to suppress the warning that would otherwise arise.  */
> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
> new file mode 100644
> index 0000000..0fa9ef4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-23.c
> @@ -0,0 +1,15 @@
> +/* PR target/32219 */
> +/* { dg-do compile } */
> +/* { dg-require-visibility "" } */
> +/* { dg-final { scan-hidden "foo" } } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> new file mode 100644
> index 0000000..5bd80a0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Common symbol with -fpie.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> new file mode 100644
> index 0000000..0cf2eb5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Common symbol with -fpic.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> new file mode 100644
> index 0000000..911f2a5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak common symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> new file mode 100644
> index 0000000..3d43439
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak common symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> new file mode 100644
> index 0000000..ee7442e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Initialized symbol with -fpie.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> new file mode 100644
> index 0000000..f261433
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Initialized symbol with -fpic.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> new file mode 100644
> index 0000000..12aaf72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak initialized symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> new file mode 100644
> index 0000000..2e4fba0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak initialized symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
> index 33f5b5d..32969fc 100644
> --- a/gcc/testsuite/gcc.target/i386/pr64317.c
> +++ b/gcc/testsuite/gcc.target/i386/pr64317.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile { target { *-*-linux* && ia32 } } } */
>  /* { dg-options "-O2 -fpie" } */
>  /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
> -/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
> +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
>  /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
>  long c;
>
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index eb65b1f..b7ef575 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6802,13 +6802,101 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution)
>           || resolution == LDPR_RESOLVED_EXEC);
>  }
>
> +static bool
> +default_binds_local_p_2 (const_tree exp, int shlib)
> +{
> +  bool local_p;
> +  bool resolved_locally = false;
> +  bool resolved_to_local_def = false;
> +
> +  /* With resolution file in hands, take look into resolutions.
> +     We can't just return true for resolved_locally symbols,
> +     because dynamic linking might overwrite symbols
> +     in shared libraries.  */
> +  if (TREE_CODE (exp) == VAR_DECL && TREE_PUBLIC (exp)
> +      && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
> +    {
> +      varpool_node *vnode = varpool_node::get (exp);
> +      /* If not building shared library, common or initialized symbols
> +        are also resolved locally, regardless they are weak or not.  */
> +      if (vnode)
> +       {
> +         if ((!shlib && vnode->definition)
> +             || vnode->in_other_partition
> +             || resolution_local_p (vnode->resolution))
> +           resolved_locally = true;
> +         if (resolution_to_local_definition_p (vnode->resolution))
> +           resolved_to_local_def = true;
> +       }
> +    }
> +  else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
> +    {
> +      struct cgraph_node *node = cgraph_node::get (exp);
> +      if (node
> +         && (resolution_local_p (node->resolution) || node->in_other_partition))
> +       resolved_locally = true;
> +      if (node
> +         && resolution_to_local_definition_p (node->resolution))
> +       resolved_to_local_def = true;
> +    }
> +
> +  /* A non-decl is an entry in the constant pool.  */
> +  if (!DECL_P (exp))
> +    local_p = true;
> +  /* Weakrefs may not bind locally, even though the weakref itself is always
> +     static and therefore local.  Similarly, the resolver for ifunc functions
> +     might resolve to a non-local function.
> +     FIXME: We can resolve the weakref case more curefuly by looking at the
> +     weakref alias.  */
> +  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
> +          || (TREE_CODE (exp) == FUNCTION_DECL
> +              && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
> +    local_p = false;
> +  /* Static variables are always local.  */
> +  else if (! TREE_PUBLIC (exp))
> +    local_p = true;
> +  /* A variable is local if the user has said explicitly that it will
> +     be and it is resolved or defined locally, not compiling for PIC or
> +     not weak.  */
> +  else if ((DECL_VISIBILITY_SPECIFIED (exp)
> +           || resolved_to_local_def)
> +          && (resolved_locally
> +              || !flag_pic
> +              || !DECL_EXTERNAL (exp)
> +              || !DECL_WEAK (exp))
> +          && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
> +    local_p = true;
> +  /* Variables defined outside this object might not be local.  */
> +  else if (DECL_EXTERNAL (exp) && !resolved_locally)
> +    local_p = false;
> +  /* If defined in this object and visibility is not default, must be
> +     local.  */
> +  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
> +    local_p = true;
> +  /* Default visibility weak data can be overridden by a strong symbol
> +     in another module and so are not local.  */
> +  else if (DECL_WEAK (exp)
> +          && !resolved_locally)
> +    local_p = false;
> +  /* If PIC, then assume that any global name can be overridden by
> +     symbols resolved from other modules.  */
> +  else if (shlib)
> +    local_p = false;
> +  /* Otherwise we're left with initialized (or non-common) global data
> +     which is of necessity defined locally.  */
> +  else
> +    local_p = true;
> +
> +  return local_p;
> +}
> +
>  /* Assume ELF-ish defaults, since that's pretty much the most liberal
>     wrt cross-module name binding.  */
>
>  bool
>  default_binds_local_p (const_tree exp)
>  {
> -  return default_binds_local_p_1 (exp, flag_shlib);
> +  return default_binds_local_p_2 (exp, flag_shlib);
>  }
>
>  bool
> @@ -7445,9 +7533,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>  {
>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>       set in order to avoid putting out names that are never really
> -     used. */
> +     used.   Always output visibility specified in the source.  */
>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> -      && targetm.binds_local_p (decl))
> +      && (DECL_VISIBILITY_SPECIFIED (decl)
> +         || targetm.binds_local_p (decl)))
>      maybe_assemble_visibility (decl);
>  }
>
> --
> 2.1.0
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07 16:45                 ` H.J. Lu
@ 2015-02-08 18:24                   ` Jack Howarth
  2015-02-09 17:26                     ` Mike Stump
  2015-02-10 21:19                   ` Richard Henderson
  1 sibling, 1 reply; 53+ messages in thread
From: Jack Howarth @ 2015-02-08 18:24 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches, Mike Stump, Iain Sandoe

H.J.,
   This last version of the patch bootstraps and passes the test suite
without regressions on x86_64-apple-darwin14.

https://gcc.gnu.org/ml/gcc-testresults/2015-02/msg00912.html

Thanks for fixing this.
           Jack

On Sat, Feb 7, 2015 at 11:45 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sat, Feb 07, 2015 at 07:56:06AM -0800, H.J. Lu wrote:
>> On Sat, Feb 07, 2015 at 10:11:01AM -0500, Jack Howarth wrote:
>> > H.J,,
>> >     Unfortunately, the answer is yes. This patch still introduces
>> > regressions in the g++ test suite.l These are all some form of...
>> >
>>
>> It looks like Darwin depends on the old behavior of
>> default_binds_local_p_1.  Please try this patch.
>>
>
> Here is an updated patch.
>
>
> H.J.
> From d010cd1ddf866f8e10fe7ad2cf483b5a872bc6ea Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 5 Feb 2015 14:28:58 -0800
> Subject: [PATCH] Handle symbol visibility/locality for PIE/PIC
>
> If a hidden weak symbol isn't defined in the TU, we can't assume it will
> be defined in another TU at link time.  It makes a difference in code
> generation when compiling for PIC. If we assume that a hidden weak
> undefined symbol is local, the address checking may be optimized out and
> leads to the wrong code.  This means that a symbol with user specified
> visibility is local only if it is locally resolved or defined, not weak
> or not compiling for PIC.  When symbol visibility is specified in the
> source, we should always output symbol visibility even if symbol isn't
> local to the TU.
>
> If a global data symbol is defined in the TU, it is always local to the
> executable, regardless if it is a common symbol or not.  If we aren't
> compiling for shared library, locally defined global data symbol binds
> locally.
>
> Since some targets call default_binds_local_p_1 directly and depend on
> the old behavior of default_binds_local_p_1.  This patch renames
> default_binds_local_p_1 to default_binds_local_p_2 and implements the
> new behavior in default_binds_local_p_2 controlled by a variable.
> The old behavior remains with default_binds_local_p_1.
>
> gcc/
>
>         PR rtl-optimization/32219
>         * cgraphunit.c (varpool_node::finalize_decl): Set definition
>         first before calling notice_global_symbol so that it is
>         available to notice_global_symbol.
>         * varasm.c (default_binds_local_p_1): Renamed to ...
>         (default_binds_local_p_2): This.  Resolve defined data symbol
>         locally if not building shared library.  Resolve symbol with
>         user specified visibility locally only if it is locally resolved
>         or defined, not weak or not compiling for PIC.
>         (default_binds_local_p): Replace default_binds_local_p_1 with
>         default_binds_local_p_2.
>         (default_binds_local_p_1): Call default_binds_local_p_2.
>         (default_elf_asm_output_external): Always output visibility
>         specified in the source.
>
> gcc/testsuite/
>
>         PR rtl-optimization/32219
>         * gcc.dg/visibility-22.c: New test.
>         * gcc.dg/visibility-23.c: Likewise.
>         * gcc.target/i386/pr32219-1.c: Likewise.
>         * gcc.target/i386/pr32219-2.c: Likewise.
>         * gcc.target/i386/pr32219-3.c: Likewise.
>         * gcc.target/i386/pr32219-4.c: Likewise.
>         * gcc.target/i386/pr32219-5.c: Likewise.
>         * gcc.target/i386/pr32219-6.c: Likewise.
>         * gcc.target/i386/pr32219-7.c: Likewise.
>         * gcc.target/i386/pr32219-8.c: Likewise.
>         * gcc.target/i386/pr64317.c: Expect GOTOFF relocation instead
>         of GOT relocation.
> ---
>  gcc/cgraphunit.c                          |  4 +-
>  gcc/testsuite/gcc.dg/visibility-22.c      | 17 +++++++++
>  gcc/testsuite/gcc.dg/visibility-23.c      | 15 ++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++
>  gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++
>  gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
>  gcc/varasm.c                              | 61 +++++++++++++++++++++----------
>  13 files changed, 209 insertions(+), 22 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
>  create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c
>
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 35b244e..71367a3 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -792,8 +792,10 @@ varpool_node::finalize_decl (tree decl)
>
>    if (node->definition)
>      return;
> -  notice_global_symbol (decl);
> +  /* Set definition first before calling notice_global_symbol so that
> +     it is available to notice_global_symbol.  */
>    node->definition = true;
> +  notice_global_symbol (decl);
>    if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
>        /* Traditionally we do not eliminate static variables when not
>          optimizing and when not doing toplevel reoder.  */
> diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
> new file mode 100644
> index 0000000..52f59be
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-22.c
> @@ -0,0 +1,17 @@
> +/* PR target/32219 */
> +/* { dg-do run } */
> +/* { dg-require-visibility "" } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +/* This test requires support for undefined weak symbols.  This support
> +   is not available on hppa*-*-hpux*.  The test is skipped rather than
> +   xfailed to suppress the warning that would otherwise arise.  */
> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
> new file mode 100644
> index 0000000..0fa9ef4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/visibility-23.c
> @@ -0,0 +1,15 @@
> +/* PR target/32219 */
> +/* { dg-do compile } */
> +/* { dg-require-visibility "" } */
> +/* { dg-final { scan-hidden "foo" } } */
> +/* { dg-options "-O2 -fPIC" { target fpic } } */
> +/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
> +
> +extern void foo () __attribute__((weak,visibility("hidden")));
> +int
> +main()
> +{
> +  if (foo)
> +    foo ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> new file mode 100644
> index 0000000..5bd80a0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Common symbol with -fpie.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> new file mode 100644
> index 0000000..0cf2eb5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Common symbol with -fpic.  */
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> new file mode 100644
> index 0000000..911f2a5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak common symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> new file mode 100644
> index 0000000..3d43439
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak common symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> new file mode 100644
> index 0000000..ee7442e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Initialized symbol with -fpie.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> new file mode 100644
> index 0000000..f261433
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Initialized symbol with -fpic.  */
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> new file mode 100644
> index 0000000..12aaf72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpie" } */
> +
> +/* Weak initialized symbol with -fpie.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> new file mode 100644
> index 0000000..2e4fba0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -fpic" } */
> +
> +/* Weak initialized symbol with -fpic.  */
> +__attribute__((weak))
> +int xxx = -1;
> +
> +int
> +foo ()
> +{
> +  return xxx;
> +}
> +
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
> +/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> +/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
> index 33f5b5d..32969fc 100644
> --- a/gcc/testsuite/gcc.target/i386/pr64317.c
> +++ b/gcc/testsuite/gcc.target/i386/pr64317.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile { target { *-*-linux* && ia32 } } } */
>  /* { dg-options "-O2 -fpie" } */
>  /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
> -/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
> +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
>  /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
>  long c;
>
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index eb65b1f..e4bc2c1 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6802,17 +6802,8 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution)
>           || resolution == LDPR_RESOLVED_EXEC);
>  }
>
> -/* Assume ELF-ish defaults, since that's pretty much the most liberal
> -   wrt cross-module name binding.  */
> -
> -bool
> -default_binds_local_p (const_tree exp)
> -{
> -  return default_binds_local_p_1 (exp, flag_shlib);
> -}
> -
> -bool
> -default_binds_local_p_1 (const_tree exp, int shlib)
> +static bool
> +default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
>  {
>    bool local_p;
>    bool resolved_locally = false;
> @@ -6826,11 +6817,18 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>      {
>        varpool_node *vnode = varpool_node::get (exp);
> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
> -       resolved_locally = true;
> -      if (vnode
> -         && resolution_to_local_definition_p (vnode->resolution))
> -       resolved_to_local_def = true;
> +      /* If not building shared library, common or initialized symbols
> +        are also resolved locally, regardless they are weak or not if
> +        weak_dominate is true.  */
> +      if (vnode)
> +       {
> +         if ((weak_dominate && !shlib && vnode->definition)
> +             || vnode->in_other_partition
> +             || resolution_local_p (vnode->resolution))
> +           resolved_locally = true;
> +         if (resolution_to_local_definition_p (vnode->resolution))
> +           resolved_to_local_def = true;
> +       }
>      }
>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>      {
> @@ -6859,9 +6857,15 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    else if (! TREE_PUBLIC (exp))
>      local_p = true;
>    /* A variable is local if the user has said explicitly that it will
> -     be.  */
> +     be and it is resolved or defined locally, not compiling for PIC,
> +     not weak or weak_dominate is false.  */
>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>             || resolved_to_local_def)
> +          && (!weak_dominate
> +              || resolved_locally
> +              || !flag_pic
> +              || !DECL_EXTERNAL (exp)
> +              || !DECL_WEAK (exp))
>            && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>      local_p = true;
>    /* Variables defined outside this object might not be local.  */
> @@ -6881,8 +6885,9 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    else if (shlib)
>      local_p = false;
>    /* Uninitialized COMMON variable may be unified with symbols
> -     resolved from other modules.  */
> +     resolved from other modules unless weak_dominate is true.  */
>    else if (DECL_COMMON (exp)
> +          && !weak_dominate
>            && !resolved_locally
>            && (DECL_INITIAL (exp) == NULL
>                || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
> @@ -6895,6 +6900,21 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    return local_p;
>  }
>
> +/* Assume ELF-ish defaults, since that's pretty much the most liberal
> +   wrt cross-module name binding.  */
> +
> +bool
> +default_binds_local_p (const_tree exp)
> +{
> +  return default_binds_local_p_2 (exp, flag_shlib != 0, true);
> +}
> +
> +bool
> +default_binds_local_p_1 (const_tree exp, int shlib)
> +{
> +  return default_binds_local_p_2 (exp, shlib != 0, false);
> +}
> +
>  /* Return true when references to DECL must bind to current definition in
>     final executable.
>
> @@ -7445,9 +7465,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>  {
>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>       set in order to avoid putting out names that are never really
> -     used. */
> +     used.   Always output visibility specified in the source.  */
>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> -      && targetm.binds_local_p (decl))
> +      && (DECL_VISIBILITY_SPECIFIED (decl)
> +         || targetm.binds_local_p (decl)))
>      maybe_assemble_visibility (decl);
>  }
>
> --
> 2.1.0
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-08 18:24                   ` Jack Howarth
@ 2015-02-09 17:26                     ` Mike Stump
  2015-02-10 18:33                       ` Jack Howarth
  0 siblings, 1 reply; 53+ messages in thread
From: Mike Stump @ 2015-02-09 17:26 UTC (permalink / raw)
  To: Jack Howarth; +Cc: H.J. Lu, GCC Patches, Iain Sandoe

On Feb 8, 2015, at 10:24 AM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>   This last version of the patch bootstraps and passes the test suite
> without regressions on x86_64-apple-darwin14.

Ok for the darwin bits.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-09 17:26                     ` Mike Stump
@ 2015-02-10 18:33                       ` Jack Howarth
  0 siblings, 0 replies; 53+ messages in thread
From: Jack Howarth @ 2015-02-10 18:33 UTC (permalink / raw)
  To: Mike Stump; +Cc: H.J. Lu, GCC Patches, Iain Sandoe

Mike,
      Actually there aren't really any darwin bits in the current patch...

https://gcc.gnu.org/ml/gcc-patches/2015-02/msg00468.html

short of the dg-skip-if adjustments for the unsupported targets.
                   Jack
ps I wonder if this final patch needs be reposted to gcc-patches as...

[PATCH][Revised] PR rtl-optimization/32219: optimizer causes wrong
code in pic/hidden/weak symbol checking

to make sure it gets the visibility for a review.


On Mon, Feb 9, 2015 at 12:25 PM, Mike Stump <mikestump@comcast.net> wrote:
> On Feb 8, 2015, at 10:24 AM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>>   This last version of the patch bootstraps and passes the test suite
>> without regressions on x86_64-apple-darwin14.
>
> Ok for the darwin bits.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-07 16:45                 ` H.J. Lu
  2015-02-08 18:24                   ` Jack Howarth
@ 2015-02-10 21:19                   ` Richard Henderson
  2015-02-10 21:25                     ` H.J. Lu
                                       ` (2 more replies)
  1 sibling, 3 replies; 53+ messages in thread
From: Richard Henderson @ 2015-02-10 21:19 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 4742 bytes --]

On 02/07/2015 08:45 AM, H.J. Lu wrote:
> Here is an updated patch.

This is an annoying comment to differentiate 3 different versions, FYI.

> @@ -6826,11 +6817,18 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>      {
>        varpool_node *vnode = varpool_node::get (exp);
> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
> -	resolved_locally = true;
> -      if (vnode
> -	  && resolution_to_local_definition_p (vnode->resolution))
> -	resolved_to_local_def = true;
> +      /* If not building shared library, common or initialized symbols
> +	 are also resolved locally, regardless they are weak or not if
> +	 weak_dominate is true.  */
> +      if (vnode)
> +	{
> +	  if ((weak_dominate && !shlib && vnode->definition)
> +	      || vnode->in_other_partition
> +	      || resolution_local_p (vnode->resolution))
> +	    resolved_locally = true;
> +	  if (resolution_to_local_definition_p (vnode->resolution))
> +	    resolved_to_local_def = true;
> +	}
>      }
>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>      {

Not the same test for a function_decl?  That's certainly a mistake.

Indeed, I believe we can now unify these two cases by using the base
symtab_node instead of varpool_node and cgraph_node.

I'm a bit confused about why we have both resolved_to_local_def vs
resolved_locally.  At least within this function, which only cares about module
locality rather than object file locality.  Honza?

> @@ -6859,9 +6857,15 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    else if (! TREE_PUBLIC (exp))
>      local_p = true;
>    /* A variable is local if the user has said explicitly that it will
> -     be.  */
> +     be and it is resolved or defined locally, not compiling for PIC,
> +     not weak or weak_dominate is false.  */
>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>  	    || resolved_to_local_def)
> +	   && (!weak_dominate
> +	       || resolved_locally
> +	       || !flag_pic
> +	       || !DECL_EXTERNAL (exp)
> +	       || !DECL_WEAK (exp))
>  	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>      local_p = true;

I think this test is conflating several issues, and as such it's very confusing.

As an existing issue, I'm not sure why "specified" visibility is any different
from unspecified visibility.  As far as I'm aware, the "specified" bit simply
means that the decl doesn't inherit inherit visibility from the class, or from
the command-line.  But once we're this far, the visibility actually applied to
the symbol should be all that matters.

Unfortunately, this test is 11 years old, from r85167.  It came in as part of
the implementation of the visibility attribute for the class.

I believe the next test should be

  else if (DECL_WEAK (exp) && !resolved_locally)
    local_p = false;

Given the change above, resolved_locally will now be true for (weak && defined
&& weak_dominate), and therefore we need not reiterate that test.

I believe the next test should be dictated by normal non-lto usage like

  extern void bar(void) __attribute__((visibility("hidden")));
  void foo(void) { ... bar(); ...)

where the user is expecting that the function call make use of a simpler
instruction sequence, probably avoiding an PLT.  Therefore

  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
    local_p = true;

Since we have already excluded undef-weak, we know that any symbol here is
either defined or strong, and non-default visibility must resolve it locally.

>    /* Variables defined outside this object might not be local.  */
> @@ -6881,8 +6885,9 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>    else if (shlib)
>      local_p = false;
>    /* Uninitialized COMMON variable may be unified with symbols
> -     resolved from other modules.  */
> +     resolved from other modules unless weak_dominate is true.  */
>    else if (DECL_COMMON (exp)
> +	   && !weak_dominate
>  	   && !resolved_locally

Like the weak test, surely weak_dominate has already been accounted for.

> @@ -7445,9 +7465,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>  {
>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>       set in order to avoid putting out names that are never really
> -     used. */
> +     used.   Always output visibility specified in the source.  */
>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
> -      && targetm.binds_local_p (decl))
> +      && (DECL_VISIBILITY_SPECIFIED (decl)
> +	  || targetm.binds_local_p (decl)))
>      maybe_assemble_visibility (decl);

Explain?

I'm testing the following in the meantime, in order to validate my hypotheses
above.


r~


[-- Attachment #2: z --]
[-- Type: text/plain, Size: 9988 bytes --]

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 48a4b35..a1ed927 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -803,8 +803,10 @@ varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 33f5b5d..32969fc 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { *-*-linux* && ia32 } } } */
 /* { dg-options "-O2 -fpie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 159fa2b..3c45f37 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -3859,6 +3859,17 @@ mark_reachable_handlers (sbitmap *r_reachablep, sbitmap *lp_reachablep)
 			      gimple_eh_dispatch_region (
                                 as_a <geh_dispatch *> (stmt)));
 	      break;
+	    case GIMPLE_CALL:
+	      if (gimple_call_builtin_p (stmt, BUILT_IN_EH_COPY_VALUES))
+		for (int i = 0; i < 2; ++i)
+		  {
+		    tree rt = gimple_call_arg (stmt, i);
+		    HOST_WIDE_INT ri = tree_to_shwi (rt);
+
+		    gcc_assert (ri = (int)ri);
+		    bitmap_set_bit (r_reachable, ri);
+		  }
+	      break;
 	    default:
 	      break;
 	    }
diff --git a/gcc/varasm.c b/gcc/varasm.c
index eb65b1f..9d041c7 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6776,123 +6776,98 @@ default_use_anchors_for_symbol_p (const_rtx symbol)
   return true;
 }
 
-/* Return true when RESOLUTION indicate that symbol will be bound to the
-   definition provided by current .o file.  */
-
 static bool
-resolution_to_local_definition_p (enum ld_plugin_symbol_resolution resolution)
+default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
 {
-  return (resolution == LDPR_PREVAILING_DEF
-	  || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
-	  || resolution == LDPR_PREVAILING_DEF_IRONLY);
-}
-
-/* Return true when RESOLUTION indicate that symbol will be bound locally
-   within current executable or DSO.  */
-
-static bool
-resolution_local_p (enum ld_plugin_symbol_resolution resolution)
-{
-  return (resolution == LDPR_PREVAILING_DEF
-	  || resolution == LDPR_PREVAILING_DEF_IRONLY
-	  || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
-	  || resolution == LDPR_PREEMPTED_REG
-	  || resolution == LDPR_PREEMPTED_IR
-	  || resolution == LDPR_RESOLVED_IR
-	  || resolution == LDPR_RESOLVED_EXEC);
-}
-
-/* Assume ELF-ish defaults, since that's pretty much the most liberal
-   wrt cross-module name binding.  */
+  /* A non-decl is an entry in the constant pool.  */
+  if (!DECL_P (exp))
+    return true;
 
-bool
-default_binds_local_p (const_tree exp)
-{
-  return default_binds_local_p_1 (exp, flag_shlib);
-}
+  /* Weakrefs may not bind locally, even though the weakref itself is always
+     static and therefore local.  Similarly, the resolver for ifunc functions
+     might resolve to a non-local function.
+     FIXME: We can resolve the weakref case more curefuly by looking at the
+     weakref alias.  */
+  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+      || (TREE_CODE (exp) == FUNCTION_DECL
+	  && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
+    return false;
 
-bool
-default_binds_local_p_1 (const_tree exp, int shlib)
-{
-  bool local_p;
-  bool resolved_locally = false;
-  bool resolved_to_local_def = false;
+  /* Static variables are always local.  */
+  if (! TREE_PUBLIC (exp))
+    return true;
 
   /* With resolution file in hands, take look into resolutions.
      We can't just return true for resolved_locally symbols,
      because dynamic linking might overwrite symbols
      in shared libraries.  */
+  symtab_node *node = NULL;
   if (TREE_CODE (exp) == VAR_DECL && TREE_PUBLIC (exp)
       && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
-    {
-      varpool_node *vnode = varpool_node::get (exp);
-      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
-	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->resolution))
-	resolved_to_local_def = true;
-    }
+    node = varpool_node::get (exp);
   else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
+    node = cgraph_node::get (exp);
+
+  bool resolved_locally = false;
+  if (node)
     {
-      struct cgraph_node *node = cgraph_node::get (exp);
-      if (node
-	  && (resolution_local_p (node->resolution) || node->in_other_partition))
+      /* When not building shared library and weak_dominate is true:
+         weak, common or initialized symbols are resolved locally.  */
+      if ((weak_dominate && !shlib && node->definition)
+	  || node->in_other_partition
+	  || node->resolution == LDPR_PREVAILING_DEF
+	  || node->resolution == LDPR_PREVAILING_DEF_IRONLY
+	  || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
+	  || node->resolution == LDPR_PREEMPTED_REG
+	  || node->resolution == LDPR_PREEMPTED_IR
+	  || node->resolution == LDPR_RESOLVED_IR
+	  || node->resolution == LDPR_RESOLVED_EXEC)
 	resolved_locally = true;
-      if (node
-	  && resolution_to_local_definition_p (node->resolution))
-	resolved_to_local_def = true;
     }
 
-  /* A non-decl is an entry in the constant pool.  */
-  if (!DECL_P (exp))
-    local_p = true;
-  /* Weakrefs may not bind locally, even though the weakref itself is always
-     static and therefore local.  Similarly, the resolver for ifunc functions
-     might resolve to a non-local function.
-     FIXME: We can resolve the weakref case more curefuly by looking at the
-     weakref alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
-	   || (TREE_CODE (exp) == FUNCTION_DECL
-	       && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
-    local_p = false;
-  /* Static variables are always local.  */
-  else if (! TREE_PUBLIC (exp))
-    local_p = true;
-  /* A variable is local if the user has said explicitly that it will
-     be.  */
-  else if ((DECL_VISIBILITY_SPECIFIED (exp)
-	    || resolved_to_local_def)
-	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
+  /* Undefined (or non-dominant) weak symbols are not defined locally.  */
+  if (DECL_WEAK (exp) && !resolved_locally)
+    return false;
+
+  /* If a strong or defined weak symbol has non-default visibility,
+     it must be defined locally.  */
+  if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
+    return true;
+
   /* Variables defined outside this object might not be local.  */
-  else if (DECL_EXTERNAL (exp) && !resolved_locally)
-    local_p = false;
-  /* If defined in this object and visibility is not default, must be
-     local.  */
-  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
-  /* Default visibility weak data can be overridden by a strong symbol
-     in another module and so are not local.  */
-  else if (DECL_WEAK (exp)
-	   && !resolved_locally)
-    local_p = false;
-  /* If PIC, then assume that any global name can be overridden by
-     symbols resolved from other modules.  */
-  else if (shlib)
-    local_p = false;
-  /* Uninitialized COMMON variable may be unified with symbols
-     resolved from other modules.  */
-  else if (DECL_COMMON (exp)
-	   && !resolved_locally
-	   && (DECL_INITIAL (exp) == NULL
-	       || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
-    local_p = false;
+  if (DECL_EXTERNAL (exp) && !resolved_locally)
+    return false;
+
+  /* When compiling for a shared library, then assume that any global name
+     can be overridden by symbols resolved from other modules.  */
+  if (shlib)
+    return false;
+
+  /* Uninitialized COMMON variable may be unified with symbols.  */
+  if (DECL_COMMON (exp)
+      && !resolved_locally
+      && (DECL_INITIAL (exp) == NULL
+	  || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
+    return false;
+
   /* Otherwise we're left with initialized (or non-common) global data
      which is of necessity defined locally.  */
-  else
-    local_p = true;
+  return true;
+}
+
+/* Assume ELF-ish defaults, since that's pretty much the most liberal
+   wrt cross-module name binding.  */
 
-  return local_p;
+bool
+default_binds_local_p (const_tree exp)
+{
+  return default_binds_local_p_2 (exp, flag_shlib != 0, true);
+}
+
+bool
+default_binds_local_p_1 (const_tree exp, int shlib)
+{
+  return default_binds_local_p_2 (exp, shlib != 0, false);
 }
 
 /* Return true when references to DECL must bind to current definition in
@@ -7445,9 +7420,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.   Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }
 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-10 21:19                   ` Richard Henderson
@ 2015-02-10 21:25                     ` H.J. Lu
  2015-02-11 14:35                     ` Jack Howarth
  2015-02-12  6:23                     ` [PATCH] PR rtl-optimization/32219: optimizer causees " Richard Henderson
  2 siblings, 0 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-10 21:25 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

On Tue, Feb 10, 2015 at 1:19 PM, Richard Henderson <rth@redhat.com> wrote:
>> @@ -7445,9 +7465,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>>  {
>>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>>       set in order to avoid putting out names that are never really
>> -     used. */
>> +     used.   Always output visibility specified in the source.  */
>>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
>> -      && targetm.binds_local_p (decl))
>> +      && (DECL_VISIBILITY_SPECIFIED (decl)
>> +       || targetm.binds_local_p (decl)))
>>      maybe_assemble_visibility (decl);
>
> Explain?
>

This is for the new testcase in my patch:

[hjl@gnu-mic-2 testsuite]$ cat gcc.dg/visibility-23.c
/* PR target/32219 */
/* { dg-do compile } */
/* { dg-require-visibility "" } */
/* { dg-final { scan-hidden "foo" } } */
/* { dg-options "-O2 -fPIC" { target fpic } } */
/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */

extern void foo () __attribute__((weak,visibility("hidden")));
int
main()
{
  if (foo)
    foo ();
  return 0;
}
[hjl@gnu-mic-2 testsuite]$

Here targetm.binds_local_p now returns false.  But we must
emit ".hidden foo" even if foo isn't defined in the TU.  Otherwise,
foo wont be hidden if it isn't defined in another TU.


-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking
  2015-02-10 21:19                   ` Richard Henderson
  2015-02-10 21:25                     ` H.J. Lu
@ 2015-02-11 14:35                     ` Jack Howarth
  2015-02-12  6:23                     ` [PATCH] PR rtl-optimization/32219: optimizer causees " Richard Henderson
  2 siblings, 0 replies; 53+ messages in thread
From: Jack Howarth @ 2015-02-11 14:35 UTC (permalink / raw)
  To: Richard Henderson
  Cc: H.J. Lu, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

Richard,
      Your proposed patch fails to bootstrap here on
x86_64-apple-darwin14 against the system clang compilers...

g++ -c   -g  -DIN_GCC    -fno-exceptions -fno-rtti
-fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings
-Wcast-qual -Wno-format -Wmissing-format-attribute
-Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros
-Wno-overlength-strings -fno-common  -DHAVE_CONFIG_H -I. -I.
-I../../gcc-5-20150211/gcc -I../../gcc-5-20150211/gcc/.
-I../../gcc-5-20150211/gcc/../include
-I../../gcc-5-20150211/gcc/../libcpp/include -I/sw/include
-I/sw/include  -I../../gcc-5-20150211/gcc/../libdecnumber
-I../../gcc-5-20150211/gcc/../libdecnumber/dpd -I../libdecnumber
-I../../gcc-5-20150211/gcc/../libbacktrace -I/sw/include -I/sw/include
-o varasm.o -MT varasm.o -MMD -MP -MF ./.deps/varasm.TPo
../../gcc-5-20150211/gcc/varasm.c
...
../../gcc-5-20150211/gcc/varasm.c:6899:9: error: use of undeclared
identifier 'resolution_to_local_definition_p'
        return resolution_to_local_definition_p (vnode->resolution);
               ^
../../gcc-5-20150211/gcc/varasm.c:6906:9: error: use of undeclared
identifier 'resolution_to_local_definition_p'
        return resolution_to_local_definition_p (node->resolution);
               ^
        Jack


On Tue, Feb 10, 2015 at 4:19 PM, Richard Henderson <rth@redhat.com> wrote:
> On 02/07/2015 08:45 AM, H.J. Lu wrote:
>> Here is an updated patch.
>
> This is an annoying comment to differentiate 3 different versions, FYI.
>
>> @@ -6826,11 +6817,18 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
>>      {
>>        varpool_node *vnode = varpool_node::get (exp);
>> -      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
>> -     resolved_locally = true;
>> -      if (vnode
>> -       && resolution_to_local_definition_p (vnode->resolution))
>> -     resolved_to_local_def = true;
>> +      /* If not building shared library, common or initialized symbols
>> +      are also resolved locally, regardless they are weak or not if
>> +      weak_dominate is true.  */
>> +      if (vnode)
>> +     {
>> +       if ((weak_dominate && !shlib && vnode->definition)
>> +           || vnode->in_other_partition
>> +           || resolution_local_p (vnode->resolution))
>> +         resolved_locally = true;
>> +       if (resolution_to_local_definition_p (vnode->resolution))
>> +         resolved_to_local_def = true;
>> +     }
>>      }
>>    else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
>>      {
>
> Not the same test for a function_decl?  That's certainly a mistake.
>
> Indeed, I believe we can now unify these two cases by using the base
> symtab_node instead of varpool_node and cgraph_node.
>
> I'm a bit confused about why we have both resolved_to_local_def vs
> resolved_locally.  At least within this function, which only cares about module
> locality rather than object file locality.  Honza?
>
>> @@ -6859,9 +6857,15 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>    else if (! TREE_PUBLIC (exp))
>>      local_p = true;
>>    /* A variable is local if the user has said explicitly that it will
>> -     be.  */
>> +     be and it is resolved or defined locally, not compiling for PIC,
>> +     not weak or weak_dominate is false.  */
>>    else if ((DECL_VISIBILITY_SPECIFIED (exp)
>>           || resolved_to_local_def)
>> +        && (!weak_dominate
>> +            || resolved_locally
>> +            || !flag_pic
>> +            || !DECL_EXTERNAL (exp)
>> +            || !DECL_WEAK (exp))
>>          && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>>      local_p = true;
>
> I think this test is conflating several issues, and as such it's very confusing.
>
> As an existing issue, I'm not sure why "specified" visibility is any different
> from unspecified visibility.  As far as I'm aware, the "specified" bit simply
> means that the decl doesn't inherit inherit visibility from the class, or from
> the command-line.  But once we're this far, the visibility actually applied to
> the symbol should be all that matters.
>
> Unfortunately, this test is 11 years old, from r85167.  It came in as part of
> the implementation of the visibility attribute for the class.
>
> I believe the next test should be
>
>   else if (DECL_WEAK (exp) && !resolved_locally)
>     local_p = false;
>
> Given the change above, resolved_locally will now be true for (weak && defined
> && weak_dominate), and therefore we need not reiterate that test.
>
> I believe the next test should be dictated by normal non-lto usage like
>
>   extern void bar(void) __attribute__((visibility("hidden")));
>   void foo(void) { ... bar(); ...)
>
> where the user is expecting that the function call make use of a simpler
> instruction sequence, probably avoiding an PLT.  Therefore
>
>   else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
>     local_p = true;
>
> Since we have already excluded undef-weak, we know that any symbol here is
> either defined or strong, and non-default visibility must resolve it locally.
>
>>    /* Variables defined outside this object might not be local.  */
>> @@ -6881,8 +6885,9 @@ default_binds_local_p_1 (const_tree exp, int shlib)
>>    else if (shlib)
>>      local_p = false;
>>    /* Uninitialized COMMON variable may be unified with symbols
>> -     resolved from other modules.  */
>> +     resolved from other modules unless weak_dominate is true.  */
>>    else if (DECL_COMMON (exp)
>> +        && !weak_dominate
>>          && !resolved_locally
>
> Like the weak test, surely weak_dominate has already been accounted for.
>
>> @@ -7445,9 +7465,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
>>  {
>>    /* We output the name if and only if TREE_SYMBOL_REFERENCED is
>>       set in order to avoid putting out names that are never really
>> -     used. */
>> +     used.   Always output visibility specified in the source.  */
>>    if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
>> -      && targetm.binds_local_p (decl))
>> +      && (DECL_VISIBILITY_SPECIFIED (decl)
>> +       || targetm.binds_local_p (decl)))
>>      maybe_assemble_visibility (decl);
>
> Explain?
>
> I'm testing the following in the meantime, in order to validate my hypotheses
> above.
>
>
> r~
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-10 21:19                   ` Richard Henderson
  2015-02-10 21:25                     ` H.J. Lu
  2015-02-11 14:35                     ` Jack Howarth
@ 2015-02-12  6:23                     ` Richard Henderson
  2015-02-12 18:16                       ` H.J. Lu
  2 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2015-02-12  6:23 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 763 bytes --]

On 02/10/2015 01:19 PM, Richard Henderson wrote:
> As an existing issue, I'm not sure why "specified" visibility is any different
> from unspecified visibility.  As far as I'm aware, the "specified" bit simply
> means that the decl doesn't inherit inherit visibility from the class, or from
> the command-line.  But once we're this far, the visibility actually applied to
> the symbol should be all that matters.

The test is there to differentiate explicit visibility from that implied from
the command-line.  Without it, we assume hidden visibility for external symbols
too early, making the command-line option useless.  This is visible even in
building libgcc.

I believe this set of patches does what we want, and cleans things up a bit in
the process.


r~

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Replace-local_p-with-direct-returns.patch --]
[-- Type: text/x-patch; name="0001-Replace-local_p-with-direct-returns.patch", Size: 3888 bytes --]

From bf5d4f20368d1173a8d586f6bdd258b00b807e33 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Wed, 11 Feb 2015 17:37:48 -0800
Subject: [PATCH 1/5] Replace local_p with direct returns

---
 gcc/varasm.c | 66 +++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 34 insertions(+), 32 deletions(-)

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 3f62fca..83d9de3 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6814,7 +6814,6 @@ default_binds_local_p (const_tree exp)
 bool
 default_binds_local_p_1 (const_tree exp, int shlib)
 {
-  bool local_p;
   bool resolved_locally = false;
   bool resolved_to_local_def = false;
 
@@ -6845,54 +6844,57 @@ default_binds_local_p_1 (const_tree exp, int shlib)
 
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
-    local_p = true;
+    return true;
+
   /* Weakrefs may not bind locally, even though the weakref itself is always
      static and therefore local.  Similarly, the resolver for ifunc functions
      might resolve to a non-local function.
      FIXME: We can resolve the weakref case more curefuly by looking at the
      weakref alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
 	   || (TREE_CODE (exp) == FUNCTION_DECL
 	       && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
-    local_p = false;
+    return false;
+
   /* Static variables are always local.  */
-  else if (! TREE_PUBLIC (exp))
-    local_p = true;
-  /* A variable is local if the user has said explicitly that it will
-     be.  */
-  else if ((DECL_VISIBILITY_SPECIFIED (exp)
-	    || resolved_to_local_def)
-	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
+  if (! TREE_PUBLIC (exp))
+    return true;
+
+  /* A variable is local if the user has said explicitly that it will be.  */
+  if ((DECL_VISIBILITY_SPECIFIED (exp) || resolved_to_local_def)
+      && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
+    return true;
+
   /* Variables defined outside this object might not be local.  */
-  else if (DECL_EXTERNAL (exp) && !resolved_locally)
-    local_p = false;
-  /* If defined in this object and visibility is not default, must be
-     local.  */
-  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
+  if (DECL_EXTERNAL (exp) && !resolved_locally)
+    return false;
+
+  /* If defined in this object and visibility is not default,
+     must be local.  */
+  if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
+    return true;
+
   /* Default visibility weak data can be overridden by a strong symbol
      in another module and so are not local.  */
-  else if (DECL_WEAK (exp)
-	   && !resolved_locally)
-    local_p = false;
+  if (DECL_WEAK (exp) && !resolved_locally)
+    return false;
+
   /* If PIC, then assume that any global name can be overridden by
      symbols resolved from other modules.  */
-  else if (shlib)
-    local_p = false;
+  if (shlib)
+    return false;
+
   /* Uninitialized COMMON variable may be unified with symbols
      resolved from other modules.  */
-  else if (DECL_COMMON (exp)
-	   && !resolved_locally
-	   && (DECL_INITIAL (exp) == NULL
-	       || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
-    local_p = false;
+  if (DECL_COMMON (exp)
+      && !resolved_locally
+      && (DECL_INITIAL (exp) == NULL
+	  || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
+    return false;
+
   /* Otherwise we're left with initialized (or non-common) global data
      which is of necessity defined locally.  */
-  else
-    local_p = true;
-
-  return local_p;
+  return true;
 }
 
 /* Return true when references to DECL must bind to current definition in
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Use-symtab_node-to-unify-var-and-function-handling.patch --]
[-- Type: text/x-patch; name="0002-Use-symtab_node-to-unify-var-and-function-handling.patch", Size: 3821 bytes --]

From 0b1ac37c688093d720a99b5ae446602a0c1120b3 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Wed, 11 Feb 2015 19:27:14 -0800
Subject: [PATCH 2/5] Use symtab_node to unify var and function handling

Delay that until after static symbols are eliminated.
---
 gcc/varasm.c | 59 +++++++++++++++++++----------------------------------------
 1 file changed, 19 insertions(+), 40 deletions(-)

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 83d9de3..dcc70e3 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6814,34 +6814,6 @@ default_binds_local_p (const_tree exp)
 bool
 default_binds_local_p_1 (const_tree exp, int shlib)
 {
-  bool resolved_locally = false;
-  bool resolved_to_local_def = false;
-
-  /* With resolution file in hands, take look into resolutions.
-     We can't just return true for resolved_locally symbols,
-     because dynamic linking might overwrite symbols
-     in shared libraries.  */
-  if (TREE_CODE (exp) == VAR_DECL && TREE_PUBLIC (exp)
-      && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
-    {
-      varpool_node *vnode = varpool_node::get (exp);
-      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
-	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->resolution))
-	resolved_to_local_def = true;
-    }
-  else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
-    {
-      struct cgraph_node *node = cgraph_node::get (exp);
-      if (node
-	  && (resolution_local_p (node->resolution) || node->in_other_partition))
-	resolved_locally = true;
-      if (node
-	  && resolution_to_local_definition_p (node->resolution))
-	resolved_to_local_def = true;
-    }
-
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
     return true;
@@ -6860,6 +6832,21 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   if (! TREE_PUBLIC (exp))
     return true;
 
+  /* With resolution file in hand, take look into resolutions.
+     We can't just return true for resolved_locally symbols,
+     because dynamic linking might overwrite symbols
+     in shared libraries.  */
+  bool resolved_locally = false;
+  bool resolved_to_local_def = false;
+  if (symtab_node *node = symtab_node::get (exp))
+    {
+      if (node->in_other_partition
+	  || resolution_local_p (node->resolution))
+	resolved_locally = true;
+      if (resolution_to_local_definition_p (node->resolution))
+	resolved_to_local_def = true;
+    }
+
   /* A variable is local if the user has said explicitly that it will be.  */
   if ((DECL_VISIBILITY_SPECIFIED (exp) || resolved_to_local_def)
       && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
@@ -6916,22 +6903,14 @@ decl_binds_to_current_def_p (const_tree decl)
     return false;
   if (!TREE_PUBLIC (decl))
     return true;
+
   /* When resolution is available, just use it.  */
-  if (TREE_CODE (decl) == VAR_DECL
-      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+  if (symtab_node *node = symtab_node::get (decl))
     {
-      varpool_node *vnode = varpool_node::get (decl);
-      if (vnode
-	  && vnode->resolution != LDPR_UNKNOWN)
-	return resolution_to_local_definition_p (vnode->resolution);
-    }
-  else if (TREE_CODE (decl) == FUNCTION_DECL)
-    {
-      struct cgraph_node *node = cgraph_node::get (decl);
-      if (node
-	  && node->resolution != LDPR_UNKNOWN)
+      if (node->resolution != LDPR_UNKNOWN)
 	return resolution_to_local_definition_p (node->resolution);
     }
+
   /* Otherwise we have to assume the worst for DECL_WEAK (hidden weaks
      binds locally but still can be overwritten), DECL_COMMON (can be merged
      with a non-common definition somewhere in the same module) or
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Don-t-use-resolution_to_local_definition_p-in-binds_.patch --]
[-- Type: text/x-patch; name="0003-Don-t-use-resolution_to_local_definition_p-in-binds_.patch", Size: 1232 bytes --]

From 2a5208dfd10bf5d9b9c63c1f7464c6b6cacbcd51 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Wed, 11 Feb 2015 19:37:25 -0800
Subject: [PATCH 3/5] Don't use resolution_to_local_definition_p in
 binds_local_p

---
 gcc/varasm.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/gcc/varasm.c b/gcc/varasm.c
index dcc70e3..f467cc0 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6837,18 +6837,15 @@ default_binds_local_p_1 (const_tree exp, int shlib)
      because dynamic linking might overwrite symbols
      in shared libraries.  */
   bool resolved_locally = false;
-  bool resolved_to_local_def = false;
   if (symtab_node *node = symtab_node::get (exp))
     {
       if (node->in_other_partition
 	  || resolution_local_p (node->resolution))
 	resolved_locally = true;
-      if (resolution_to_local_definition_p (node->resolution))
-	resolved_to_local_def = true;
     }
 
   /* A variable is local if the user has said explicitly that it will be.  */
-  if ((DECL_VISIBILITY_SPECIFIED (exp) || resolved_to_local_def)
+  if (DECL_VISIBILITY_SPECIFIED (exp)
       && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     return true;
 
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-Add-weak_dominate-logic.patch --]
[-- Type: text/x-patch; name="0004-Add-weak_dominate-logic.patch", Size: 2952 bytes --]

From aa50d80d97a27e99cc295e3f2a00662dc73ce235 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Wed, 11 Feb 2015 20:11:09 -0800
Subject: [PATCH 4/5] Add weak_dominate logic

---
 gcc/varasm.c | 42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/gcc/varasm.c b/gcc/varasm.c
index f467cc0..dea9b36 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6802,17 +6802,8 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution)
 	  || resolution == LDPR_RESOLVED_EXEC);
 }
 
-/* Assume ELF-ish defaults, since that's pretty much the most liberal
-   wrt cross-module name binding.  */
-
-bool
-default_binds_local_p (const_tree exp)
-{
-  return default_binds_local_p_1 (exp, flag_shlib);
-}
-
-bool
-default_binds_local_p_1 (const_tree exp, int shlib)
+static bool
+default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
 {
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
@@ -6839,11 +6830,18 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   bool resolved_locally = false;
   if (symtab_node *node = symtab_node::get (exp))
     {
-      if (node->in_other_partition
+      /* When not building shared library and weak_dominate is true:
+         weak, common or initialized symbols are resolved locally.  */
+      if ((weak_dominate && !shlib && node->definition)
+	  || node->in_other_partition
 	  || resolution_local_p (node->resolution))
 	resolved_locally = true;
     }
 
+  /* Undefined (or non-dominant) weak symbols are not defined locally.  */
+  if (DECL_WEAK (exp) && !resolved_locally)
+    return false;
+
   /* A variable is local if the user has said explicitly that it will be.  */
   if (DECL_VISIBILITY_SPECIFIED (exp)
       && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
@@ -6858,11 +6856,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     return true;
 
-  /* Default visibility weak data can be overridden by a strong symbol
-     in another module and so are not local.  */
-  if (DECL_WEAK (exp) && !resolved_locally)
-    return false;
-
   /* If PIC, then assume that any global name can be overridden by
      symbols resolved from other modules.  */
   if (shlib)
@@ -6881,6 +6874,21 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   return true;
 }
 
+/* Assume ELF-ish defaults, since that's pretty much the most liberal
+   wrt cross-module name binding.  */
+
+bool
+default_binds_local_p (const_tree exp)
+{
+  return default_binds_local_p_2 (exp, flag_shlib != 0, true);
+}
+
+bool
+default_binds_local_p_1 (const_tree exp, int shlib)
+{
+  return default_binds_local_p_2 (exp, shlib != 0, false);
+}
+
 /* Return true when references to DECL must bind to current definition in
    final executable.
 
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-Rest-of-HJL-patch.patch --]
[-- Type: text/x-patch; name="0005-Rest-of-HJL-patch.patch", Size: 11482 bytes --]

From 81db9e951ac27c9a7f94f88546d90c852a927d54 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Wed, 11 Feb 2015 22:16:38 -0800
Subject: [PATCH 5/5] Rest of HJL patch

---
 gcc/cgraphunit.c                          |  4 +++-
 gcc/testsuite/gcc.dg/visibility-22.c      | 17 +++++++++++++++++
 gcc/testsuite/gcc.dg/visibility-23.c      | 15 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-1.c | 16 ++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-2.c | 16 ++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-3.c | 17 +++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-4.c | 17 +++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-5.c | 16 ++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-6.c | 16 ++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-7.c | 17 +++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr32219-8.c | 17 +++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr64317.c   |  2 +-
 gcc/varasm.c                              |  5 +++--
 13 files changed, 171 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/visibility-22.c
 create mode 100644 gcc/testsuite/gcc.dg/visibility-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr32219-8.c

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index f2c40d4..057eedb 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -803,8 +803,10 @@ varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
new file mode 100644
index 0000000..52f59be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-22.c
@@ -0,0 +1,17 @@
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* This test requires support for undefined weak symbols.  This support
+   is not available on hppa*-*-hpux*.  The test is skipped rather than
+   xfailed to suppress the warning that would otherwise arise.  */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
new file mode 100644
index 0000000..0fa9ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-23.c
@@ -0,0 +1,15 @@
+/* PR target/32219 */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "foo" } } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
new file mode 100644
index 0000000..5bd80a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Common symbol with -fpie.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
new file mode 100644
index 0000000..0cf2eb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
new file mode 100644
index 0000000..911f2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak common symbol with -fpie.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
new file mode 100644
index 0000000..3d43439
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
new file mode 100644
index 0000000..ee7442e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Initialized symbol with -fpie.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
new file mode 100644
index 0000000..f261433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
new file mode 100644
index 0000000..12aaf72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak initialized symbol with -fpie.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
new file mode 100644
index 0000000..2e4fba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 33f5b5d..32969fc 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { *-*-linux* && ia32 } } } */
 /* { dg-options "-O2 -fpie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index dea9b36..9f79416 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -7435,9 +7435,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.  Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }
 
-- 
2.1.0


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12  6:23                     ` [PATCH] PR rtl-optimization/32219: optimizer causees " Richard Henderson
@ 2015-02-12 18:16                       ` H.J. Lu
  2015-02-12 18:58                         ` H.J. Lu
  2015-02-12 19:16                         ` Jack Howarth
  0 siblings, 2 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-12 18:16 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

On Wed, Feb 11, 2015 at 10:22 PM, Richard Henderson <rth@redhat.com> wrote:
> On 02/10/2015 01:19 PM, Richard Henderson wrote:
>> As an existing issue, I'm not sure why "specified" visibility is any different
>> from unspecified visibility.  As far as I'm aware, the "specified" bit simply
>> means that the decl doesn't inherit inherit visibility from the class, or from
>> the command-line.  But once we're this far, the visibility actually applied to
>> the symbol should be all that matters.
>
> The test is there to differentiate explicit visibility from that implied from
> the command-line.  Without it, we assume hidden visibility for external symbols
> too early, making the command-line option useless.  This is visible even in
> building libgcc.
>
> I believe this set of patches does what we want, and cleans things up a bit in
> the process.
>
>

I tried them on Linux/x86-64.  They caused:

FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
scan-assembler-not _ZTW1i@PLT
FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
scan-assembler-not _ZTW1i@PLT
FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
scan-assembler-not _ZTW1i@PLT
FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
scan-assembler-not _ZTW1i@PLT


-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 18:16                       ` H.J. Lu
@ 2015-02-12 18:58                         ` H.J. Lu
  2015-02-12 19:25                           ` Richard Henderson
  2015-02-12 19:16                         ` Jack Howarth
  1 sibling, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-12 18:58 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 1705 bytes --]

On Thu, Feb 12, 2015 at 10:16 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Feb 11, 2015 at 10:22 PM, Richard Henderson <rth@redhat.com> wrote:
>> On 02/10/2015 01:19 PM, Richard Henderson wrote:
>>> As an existing issue, I'm not sure why "specified" visibility is any different
>>> from unspecified visibility.  As far as I'm aware, the "specified" bit simply
>>> means that the decl doesn't inherit inherit visibility from the class, or from
>>> the command-line.  But once we're this far, the visibility actually applied to
>>> the symbol should be all that matters.
>>
>> The test is there to differentiate explicit visibility from that implied from
>> the command-line.  Without it, we assume hidden visibility for external symbols
>> too early, making the command-line option useless.  This is visible even in
>> building libgcc.
>>
>> I believe this set of patches does what we want, and cleans things up a bit in
>> the process.
>>
>>
>
> I tried them on Linux/x86-64.  They caused:
>
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
> scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
> scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
> scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
> scan-assembler-not _ZTW1i@PLT
>

I am testing this patch on top of yours.


-- 
H.J.

[-- Attachment #2: 0001-A-variable-is-local-if-specified-by-user.patch --]
[-- Type: text/x-patch, Size: 1499 bytes --]

From 3b516badec25151acd4a96fa4ef07b3f88e3f053 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 12 Feb 2015 10:55:55 -0800
Subject: [PATCH] A variable is local if specified by user

And it is resolved or defined locally, not compiling for PIC or not weak.
---
 gcc/varasm.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 9f79416..b14f2d3 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6838,15 +6838,21 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
 	resolved_locally = true;
     }
 
-  /* Undefined (or non-dominant) weak symbols are not defined locally.  */
-  if (DECL_WEAK (exp) && !resolved_locally)
-    return false;
-
-  /* A variable is local if the user has said explicitly that it will be.  */
+  /* A variable is local if the user has said explicitly that it will
+     be and it is resolved or defined locally, not compiling for PIC or
+     not weak.  */
   if (DECL_VISIBILITY_SPECIFIED (exp)
+      && (resolved_locally
+	  || !flag_pic
+	  || !DECL_EXTERNAL (exp)
+	  || !DECL_WEAK (exp))
       && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     return true;
 
+  /* Undefined (or non-dominant) weak symbols are not defined locally.  */
+  if (DECL_WEAK (exp) && !resolved_locally)
+    return false;
+
   /* Variables defined outside this object might not be local.  */
   if (DECL_EXTERNAL (exp) && !resolved_locally)
     return false;
-- 
1.9.3


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 18:16                       ` H.J. Lu
  2015-02-12 18:58                         ` H.J. Lu
@ 2015-02-12 19:16                         ` Jack Howarth
  2015-02-12 19:18                           ` H.J. Lu
  1 sibling, 1 reply; 53+ messages in thread
From: Jack Howarth @ 2015-02-12 19:16 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Richard Henderson, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

H.J.,
   Oddly I saw no regressions in the g++ test suite at -m32/-m64 on
x86_64-apple-darwin14.
           Jack

On Thu, Feb 12, 2015 at 1:16 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Feb 11, 2015 at 10:22 PM, Richard Henderson <rth@redhat.com> wrote:
>> On 02/10/2015 01:19 PM, Richard Henderson wrote:
>>> As an existing issue, I'm not sure why "specified" visibility is any different
>>> from unspecified visibility.  As far as I'm aware, the "specified" bit simply
>>> means that the decl doesn't inherit inherit visibility from the class, or from
>>> the command-line.  But once we're this far, the visibility actually applied to
>>> the symbol should be all that matters.
>>
>> The test is there to differentiate explicit visibility from that implied from
>> the command-line.  Without it, we assume hidden visibility for external symbols
>> too early, making the command-line option useless.  This is visible even in
>> building libgcc.
>>
>> I believe this set of patches does what we want, and cleans things up a bit in
>> the process.
>>
>>
>
> I tried them on Linux/x86-64.  They caused:
>
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
> scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
> scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
> scan-assembler-not _ZTW1i@PLT
> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
> scan-assembler-not _ZTW1i@PLT
>
>
> --
> H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 19:16                         ` Jack Howarth
@ 2015-02-12 19:18                           ` H.J. Lu
  2015-02-12 19:39                             ` Jack Howarth
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-12 19:18 UTC (permalink / raw)
  To: Jack Howarth
  Cc: Richard Henderson, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

On Thu, Feb 12, 2015 at 11:16 AM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
> H.J.,
>    Oddly I saw no regressions in the g++ test suite at -m32/-m64 on
> x86_64-apple-darwin14.
>            Jack

They have

// { dg-require-effective-target tls }

Does x86_64-apple-darwin14 support TLS?  If yes, what does the
generated assembly code look like?

> On Thu, Feb 12, 2015 at 1:16 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Wed, Feb 11, 2015 at 10:22 PM, Richard Henderson <rth@redhat.com> wrote:
>>> On 02/10/2015 01:19 PM, Richard Henderson wrote:
>>>> As an existing issue, I'm not sure why "specified" visibility is any different
>>>> from unspecified visibility.  As far as I'm aware, the "specified" bit simply
>>>> means that the decl doesn't inherit inherit visibility from the class, or from
>>>> the command-line.  But once we're this far, the visibility actually applied to
>>>> the symbol should be all that matters.
>>>
>>> The test is there to differentiate explicit visibility from that implied from
>>> the command-line.  Without it, we assume hidden visibility for external symbols
>>> too early, making the command-line option useless.  This is visible even in
>>> building libgcc.
>>>
>>> I believe this set of patches does what we want, and cleans things up a bit in
>>> the process.
>>>
>>>
>>
>> I tried them on Linux/x86-64.  They caused:
>>
>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
>> scan-assembler-not _ZTW1i@PLT
>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
>> scan-assembler-not _ZTW1i@PLT
>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
>> scan-assembler-not _ZTW1i@PLT
>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
>> scan-assembler-not _ZTW1i@PLT
>>
>>
>> --
>> H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 18:58                         ` H.J. Lu
@ 2015-02-12 19:25                           ` Richard Henderson
  2015-02-12 23:04                             ` H.J. Lu
  0 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2015-02-12 19:25 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

On 02/12/2015 10:58 AM, H.J. Lu wrote:
>    if (DECL_VISIBILITY_SPECIFIED (exp)
> +      && (resolved_locally
> +	  || !flag_pic

Yes, this essentially goes back to your original patch, which I claim still
conflates issues.

In particular, I believe mentioning flag_pic here is a serious error.

There are two problems that I see so far,

 (1) node->definition isn't set for this symbol.  This is because you
     only fixed varpool_node::finalize_decl, and not
     cgraph_node::finalize_function.

 (2) The weak test should probably be split into two pieces, like the
     visibility test: exclude undefined weak, include specified visibility,
     exclude non-dominant weak, exclude external, include implied visibility.


r~

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 19:18                           ` H.J. Lu
@ 2015-02-12 19:39                             ` Jack Howarth
  0 siblings, 0 replies; 53+ messages in thread
From: Jack Howarth @ 2015-02-12 19:39 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Richard Henderson, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 4207 bytes --]

On Thu, Feb 12, 2015 at 2:18 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Feb 12, 2015 at 11:16 AM, Jack Howarth <howarth.at.gcc@gmail.com> wrote:
>> H.J.,
>>    Oddly I saw no regressions in the g++ test suite at -m32/-m64 on
>> x86_64-apple-darwin14.
>>            Jack
>
> They have
>
> // { dg-require-effective-target tls }
>
> Does x86_64-apple-darwin14 support TLS?  If yes, what does the
> generated assembly code look like?

We use emutls on darwin. Those failing test are run at -m32/-m64...

Executing on host:
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/gcc/testsuite/g++.dg/gomp/tls-wrap4.C
 -fno-diagnostics-show-caret -fdiagnostics-color=never  -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin13.4.0/libstdc++-v3/include/x86_64-apple-darwin13.4.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin13.4.0/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/libstdc++-v3/testsuite/util
-fmessage-length=0  -std=gnu++11 -fPIC  -S  -m64  -o tls-wrap4.s
(timeout = 300)
spawn -ignore SIGHUP
/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../xg++
-B/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/gcc/testsuite/g++/../../
/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/gcc/testsuite/g++.dg/gomp/tls-wrap4.C
-fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin13.4.0/libstdc++-v3/include/x86_64-apple-darwin13.4.0
-I/sw/src/fink.build/gcc50-5.0.0-1000/darwin_objdir/x86_64-apple-darwin13.4.0/libstdc++-v3/include
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/libstdc++-v3/libsupc++
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/libstdc++-v3/include/backward
-I/sw/src/fink.build/gcc50-5.0.0-1000/gcc-5-20150212/libstdc++-v3/testsuite/util
-fmessage-length=0 -std=gnu++11 -fPIC -S -m64 -o tls-wrap4.s^M
PASS: g++.dg/gomp/tls-wrap4.C  -std=gnu++11 (test for excess errors)
PASS: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT

and produce the attached assembly.
                Jack

>
>> On Thu, Feb 12, 2015 at 1:16 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Wed, Feb 11, 2015 at 10:22 PM, Richard Henderson <rth@redhat.com> wrote:
>>>> On 02/10/2015 01:19 PM, Richard Henderson wrote:
>>>>> As an existing issue, I'm not sure why "specified" visibility is any different
>>>>> from unspecified visibility.  As far as I'm aware, the "specified" bit simply
>>>>> means that the decl doesn't inherit inherit visibility from the class, or from
>>>>> the command-line.  But once we're this far, the visibility actually applied to
>>>>> the symbol should be all that matters.
>>>>
>>>> The test is there to differentiate explicit visibility from that implied from
>>>> the command-line.  Without it, we assume hidden visibility for external symbols
>>>> too early, making the command-line option useless.  This is visible even in
>>>> building libgcc.
>>>>
>>>> I believe this set of patches does what we want, and cleans things up a bit in
>>>> the process.
>>>>
>>>>
>>>
>>> I tried them on Linux/x86-64.  They caused:
>>>
>>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
>>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++11  scan-assembler-not _ZTW1i@PLT
>>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
>>> FAIL: g++.dg/gomp/tls-wrap4.C  -std=gnu++14  scan-assembler-not _ZTW1i@PLT
>>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
>>> scan-assembler-not _ZTW1i@PLT
>>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++11
>>> scan-assembler-not _ZTW1i@PLT
>>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
>>> scan-assembler-not _ZTW1i@PLT
>>> FAIL: g++.dg/tls/thread_local-wrap4.C  -std=gnu++14
>>> scan-assembler-not _ZTW1i@PLT
>>>
>>>
>>> --
>>> H.J.
>
>
>
> --
> H.J.

[-- Attachment #2: tls-wrap4.s --]
[-- Type: application/octet-stream, Size: 1668 bytes --]

	.section __TEXT,__textcoal_nt,coalesced,pure_instructions
	.globl __ZTW1i
	.weak_definition __ZTW1i
	.private_extern __ZTW1i
__ZTW1i:
LFB1:
	pushq	%rbp
LCFI0:
	movq	%rsp, %rbp
LCFI1:
	movq	___emutls_v.i@GOTPCREL(%rip), %rax
	movq	%rax, %rdi
	call	___emutls_get_address
	popq	%rbp
LCFI2:
	ret
LFE1:
	.text
	.globl _main
_main:
LFB0:
	pushq	%rbp
LCFI3:
	movq	%rsp, %rbp
LCFI4:
	call	__ZTW1i
	movl	(%rax), %eax
	subl	$42, %eax
	popq	%rbp
LCFI5:
	ret
LFE0:
	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
	.set L$set$0,LECIE1-LSCIE1
	.long L$set$0
LSCIE1:
	.long	0
	.byte	0x1
	.ascii "zR\0"
	.byte	0x1
	.byte	0x78
	.byte	0x10
	.byte	0x1
	.byte	0x10
	.byte	0xc
	.byte	0x7
	.byte	0x8
	.byte	0x90
	.byte	0x1
	.align 3
LECIE1:
LSFDE1:
	.set L$set$1,LEFDE1-LASFDE1
	.long L$set$1
LASFDE1:
	.long	LASFDE1-EH_frame1
	.quad	LFB1-.
	.set L$set$2,LFE1-LFB1
	.quad L$set$2
	.byte	0
	.byte	0x4
	.set L$set$3,LCFI0-LFB1
	.long L$set$3
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$4,LCFI1-LCFI0
	.long L$set$4
	.byte	0xd
	.byte	0x6
	.byte	0x4
	.set L$set$5,LCFI2-LCFI1
	.long L$set$5
	.byte	0xc
	.byte	0x7
	.byte	0x8
	.align 3
LEFDE1:
LSFDE3:
	.set L$set$6,LEFDE3-LASFDE3
	.long L$set$6
LASFDE3:
	.long	LASFDE3-EH_frame1
	.quad	LFB0-.
	.set L$set$7,LFE0-LFB0
	.quad L$set$7
	.byte	0
	.byte	0x4
	.set L$set$8,LCFI3-LFB0
	.long L$set$8
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$9,LCFI4-LCFI3
	.long L$set$9
	.byte	0xd
	.byte	0x6
	.byte	0x4
	.set L$set$10,LCFI5-LCFI4
	.long L$set$10
	.byte	0xc
	.byte	0x7
	.byte	0x8
	.align 3
LEFDE3:
	.constructor
	.destructor
	.align 1
	.subsections_via_symbols

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 19:25                           ` Richard Henderson
@ 2015-02-12 23:04                             ` H.J. Lu
  2015-02-12 23:05                               ` H.J. Lu
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-12 23:04 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 870 bytes --]

On Thu, Feb 12, 2015 at 11:25 AM, Richard Henderson <rth@redhat.com> wrote:
> On 02/12/2015 10:58 AM, H.J. Lu wrote:
>>    if (DECL_VISIBILITY_SPECIFIED (exp)
>> +      && (resolved_locally
>> +       || !flag_pic
>
> Yes, this essentially goes back to your original patch, which I claim still
> conflates issues.
>
> In particular, I believe mentioning flag_pic here is a serious error.
>
> There are two problems that I see so far,
>
>  (1) node->definition isn't set for this symbol.  This is because you
>      only fixed varpool_node::finalize_decl, and not
>      cgraph_node::finalize_function.
>
>  (2) The weak test should probably be split into two pieces, like the
>      visibility test: exclude undefined weak, include specified visibility,
>      exclude non-dominant weak, exclude external, include implied visibility.
>

How about this patch?


-- 
H.J.

[-- Attachment #2: 0001-A-variable-is-local-if-specified-by-user.patch --]
[-- Type: text/x-patch, Size: 1499 bytes --]

From 3b516badec25151acd4a96fa4ef07b3f88e3f053 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 12 Feb 2015 10:55:55 -0800
Subject: [PATCH] A variable is local if specified by user

And it is resolved or defined locally, not compiling for PIC or not weak.
---
 gcc/varasm.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 9f79416..b14f2d3 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6838,15 +6838,21 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
 	resolved_locally = true;
     }
 
-  /* Undefined (or non-dominant) weak symbols are not defined locally.  */
-  if (DECL_WEAK (exp) && !resolved_locally)
-    return false;
-
-  /* A variable is local if the user has said explicitly that it will be.  */
+  /* A variable is local if the user has said explicitly that it will
+     be and it is resolved or defined locally, not compiling for PIC or
+     not weak.  */
   if (DECL_VISIBILITY_SPECIFIED (exp)
+      && (resolved_locally
+	  || !flag_pic
+	  || !DECL_EXTERNAL (exp)
+	  || !DECL_WEAK (exp))
       && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     return true;
 
+  /* Undefined (or non-dominant) weak symbols are not defined locally.  */
+  if (DECL_WEAK (exp) && !resolved_locally)
+    return false;
+
   /* Variables defined outside this object might not be local.  */
   if (DECL_EXTERNAL (exp) && !resolved_locally)
     return false;
-- 
1.9.3


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 23:04                             ` H.J. Lu
@ 2015-02-12 23:05                               ` H.J. Lu
  2015-02-13  0:05                                 ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-12 23:05 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 986 bytes --]

On Thu, Feb 12, 2015 at 3:04 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Feb 12, 2015 at 11:25 AM, Richard Henderson <rth@redhat.com> wrote:
>> On 02/12/2015 10:58 AM, H.J. Lu wrote:
>>>    if (DECL_VISIBILITY_SPECIFIED (exp)
>>> +      && (resolved_locally
>>> +       || !flag_pic
>>
>> Yes, this essentially goes back to your original patch, which I claim still
>> conflates issues.
>>
>> In particular, I believe mentioning flag_pic here is a serious error.
>>
>> There are two problems that I see so far,
>>
>>  (1) node->definition isn't set for this symbol.  This is because you
>>      only fixed varpool_node::finalize_decl, and not
>>      cgraph_node::finalize_function.
>>
>>  (2) The weak test should probably be split into two pieces, like the
>>      visibility test: exclude undefined weak, include specified visibility,
>>      exclude non-dominant weak, exclude external, include implied visibility.
>>
>
> How about this patch?
>

Oops.  Wrong one.


-- 
H.J.

[-- Attachment #2: 0001-non-default-visibility-is-local.patch --]
[-- Type: text/x-patch, Size: 1899 bytes --]

From afbb56ab924d9f419ac4f65f5c535ebdbd22f16e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 12 Feb 2015 15:03:00 -0800
Subject: [PATCH] non-default visibility is local

---
 gcc/cgraphunit.c |  4 +++-
 gcc/varasm.c     | 12 +++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 057eedb..942826d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -442,8 +442,10 @@ cgraph_node::finalize_function (tree decl, bool no_collect)
       node->local.redefined_extern_inline = true;
     }
 
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
 
   /* With -fkeep-inline-functions we are keeping all inline functions except
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 9f79416..5d7cba1 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6830,9 +6830,15 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
   bool resolved_locally = false;
   if (symtab_node *node = symtab_node::get (exp))
     {
-      /* When not building shared library and weak_dominate is true:
-         weak, common or initialized symbols are resolved locally.  */
-      if ((weak_dominate && !shlib && node->definition)
+      /* When weak_dominate is true and not building shared library or
+	 non-default visibility is specified by user: weak, common or
+	 initialized symbols are resolved locally.
+	 */
+      if (((!shlib
+	    || (DECL_VISIBILITY_SPECIFIED (exp)
+		&& DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT))
+	   && weak_dominate
+	   && node->definition)
 	  || node->in_other_partition
 	  || resolution_local_p (node->resolution))
 	resolved_locally = true;
-- 
1.9.3


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-12 23:05                               ` H.J. Lu
@ 2015-02-13  0:05                                 ` Richard Henderson
  2015-02-13  4:14                                   ` H.J. Lu
  0 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2015-02-13  0:05 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 1895 bytes --]

On 02/12/2015 03:05 PM, H.J. Lu wrote:
> @@ -6830,9 +6830,15 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
>    bool resolved_locally = false;
>    if (symtab_node *node = symtab_node::get (exp))
>      {
> -      /* When not building shared library and weak_dominate is true:
> -         weak, common or initialized symbols are resolved locally.  */
> -      if ((weak_dominate && !shlib && node->definition)
> +      /* When weak_dominate is true and not building shared library or
> +	 non-default visibility is specified by user: weak, common or
> +	 initialized symbols are resolved locally.
> +	 */
> +      if (((!shlib
> +	    || (DECL_VISIBILITY_SPECIFIED (exp)
> +		&& DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT))
> +	   && weak_dominate
> +	   && node->definition)
>  	  || node->in_other_partition
>  	  || resolution_local_p (node->resolution))
>  	resolved_locally = true;

Hum.  I don't find that particularly easy to reason with either.

How about this?  I'm about half-way through regression testing on it.

I re-instated the use of resolution_to_local_definition_p, and attempt to infer
a proper value for that when lto isn't in use.  I use this to eliminate only
undef-weak early, rather than non-dominate weak.

I re-instated the use of the existence of the local definition in the
DECL_VISIBILITY test.  But unlike before, I reason that this allows us to
eliminate the second visibility check.  We either have an assertion from the
user (SPECIFIED), or we know we have a definition.  We no longer rely on the
DECL_EXTERNAL test in the middle eliminating symbols without a definition.

I shuffled some of the "return false" tests around among themselves, attempting
to put the simplest test first.  No change in behavior there.

(First patch is delta from the 5-patch bundle; second patch is the
composite from trunk, to avoid confusion.)


r~

[-- Attachment #2: zz --]
[-- Type: text/plain, Size: 3243 bytes --]

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 057eedb..942826d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -442,8 +442,10 @@ cgraph_node::finalize_function (tree decl, bool no_collect)
       node->local.redefined_extern_inline = true;
     }
 
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
 
   /* With -fkeep-inline-functions we are keeping all inline functions except
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 9f79416..0211306 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6828,37 +6828,42 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
      because dynamic linking might overwrite symbols
      in shared libraries.  */
   bool resolved_locally = false;
+  bool defined_locally = false;
   if (symtab_node *node = symtab_node::get (exp))
     {
-      /* When not building shared library and weak_dominate is true:
-         weak, common or initialized symbols are resolved locally.  */
-      if ((weak_dominate && !shlib && node->definition)
-	  || node->in_other_partition
-	  || resolution_local_p (node->resolution))
+      if (node->definition || node->in_other_partition)
+	{
+	  defined_locally = true;
+	  resolved_locally = (weak_dominate && !shlib);
+	}
+      if (resolution_to_local_definition_p (node->resolution))
+	defined_locally = resolved_locally = true;
+      else if (resolution_local_p (node->resolution))
 	resolved_locally = true;
     }
 
-  /* Undefined (or non-dominant) weak symbols are not defined locally.  */
-  if (DECL_WEAK (exp) && !resolved_locally)
+  /* Undefined weak symbols are never defined locally.  */
+  if (DECL_WEAK (exp) && !defined_locally)
     return false;
 
-  /* A variable is local if the user has said explicitly that it will be.  */
-  if (DECL_VISIBILITY_SPECIFIED (exp)
-      && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
+  /* A symbol is local if the user has said explicitly that it will be,
+     or if we have a definition for the symbol.  We cannot infer visibility
+     for undefined symbols.  */
+  if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT
+      && (DECL_VISIBILITY_SPECIFIED (exp) || defined_locally))
     return true;
 
+  /* If PIC, then assume that any global name can be overridden by
+     symbols resolved from other modules.  */
+  if (shlib)
+    return false;
+
   /* Variables defined outside this object might not be local.  */
   if (DECL_EXTERNAL (exp) && !resolved_locally)
     return false;
 
-  /* If defined in this object and visibility is not default,
-     must be local.  */
-  if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    return true;
-
-  /* If PIC, then assume that any global name can be overridden by
-     symbols resolved from other modules.  */
-  if (shlib)
+  /* Non-dominant weak symbols are not defined locally.  */
+  if (DECL_WEAK (exp) && !resolved_locally)
     return false;
 
   /* Uninitialized COMMON variable may be unified with symbols

[-- Attachment #3: z3 --]
[-- Type: text/plain, Size: 17327 bytes --]

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index f2c40d4..942826d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -442,8 +442,10 @@ cgraph_node::finalize_function (tree decl, bool no_collect)
       node->local.redefined_extern_inline = true;
     }
 
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
 
   /* With -fkeep-inline-functions we are keeping all inline functions except
@@ -803,8 +805,10 @@ varpool_node::finalize_decl (tree decl)
 
   if (node->definition)
     return;
-  notice_global_symbol (decl);
+  /* Set definition first before calling notice_global_symbol so that
+     it is available to notice_global_symbol.  */
   node->definition = true;
+  notice_global_symbol (decl);
   if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
       /* Traditionally we do not eliminate static variables when not
 	 optimizing and when not doing toplevel reoder.  */
diff --git a/gcc/testsuite/gcc.dg/visibility-22.c b/gcc/testsuite/gcc.dg/visibility-22.c
new file mode 100644
index 0000000..52f59be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-22.c
@@ -0,0 +1,17 @@
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* This test requires support for undefined weak symbols.  This support
+   is not available on hppa*-*-hpux*.  The test is skipped rather than
+   xfailed to suppress the warning that would otherwise arise.  */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/visibility-23.c b/gcc/testsuite/gcc.dg/visibility-23.c
new file mode 100644
index 0000000..0fa9ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/visibility-23.c
@@ -0,0 +1,15 @@
+/* PR target/32219 */
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-hidden "foo" } } */
+/* { dg-options "-O2 -fPIC" { target fpic } } */
+/* { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "*-*-darwin*" } "*" { "" } }  */
+
+extern void foo () __attribute__((weak,visibility("hidden")));
+int
+main()
+{
+  if (foo)
+    foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c
new file mode 100644
index 0000000..5bd80a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Common symbol with -fpie.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-2.c b/gcc/testsuite/gcc.target/i386/pr32219-2.c
new file mode 100644
index 0000000..0cf2eb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Common symbol with -fpic.  */
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-3.c b/gcc/testsuite/gcc.target/i386/pr32219-3.c
new file mode 100644
index 0000000..911f2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak common symbol with -fpie.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-4.c b/gcc/testsuite/gcc.target/i386/pr32219-4.c
new file mode 100644
index 0000000..3d43439
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak common symbol with -fpic.  */
+__attribute__((weak))
+int xxx;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-5.c b/gcc/testsuite/gcc.target/i386/pr32219-5.c
new file mode 100644
index 0000000..ee7442e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Initialized symbol with -fpie.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-6.c b/gcc/testsuite/gcc.target/i386/pr32219-6.c
new file mode 100644
index 0000000..f261433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-6.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Initialized symbol with -fpic.  */
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-7.c b/gcc/testsuite/gcc.target/i386/pr32219-7.c
new file mode 100644
index 0000000..12aaf72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-7.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpie" } */
+
+/* Weak initialized symbol with -fpie.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr32219-8.c b/gcc/testsuite/gcc.target/i386/pr32219-8.c
new file mode 100644
index 0000000..2e4fba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr32219-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+/* Weak initialized symbol with -fpic.  */
+__attribute__((weak))
+int xxx = -1;
+
+int
+foo ()
+{
+  return xxx;
+}
+
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "xxx@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "movl\[ \t\]xxx@GOTOFF\\(%\[^,\]*\\), %eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "movl\[ \t\]xxx@GOT\\(%\[^,\]*\\), %eax" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c
index 33f5b5d..32969fc 100644
--- a/gcc/testsuite/gcc.target/i386/pr64317.c
+++ b/gcc/testsuite/gcc.target/i386/pr64317.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { *-*-linux* && ia32 } } } */
 /* { dg-options "-O2 -fpie" } */
 /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */
-/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */
+/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */
 /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */
 long c;
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 3f62fca..0211306 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6802,97 +6802,96 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution)
 	  || resolution == LDPR_RESOLVED_EXEC);
 }
 
-/* Assume ELF-ish defaults, since that's pretty much the most liberal
-   wrt cross-module name binding.  */
-
-bool
-default_binds_local_p (const_tree exp)
-{
-  return default_binds_local_p_1 (exp, flag_shlib);
-}
-
-bool
-default_binds_local_p_1 (const_tree exp, int shlib)
+static bool
+default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
 {
-  bool local_p;
-  bool resolved_locally = false;
-  bool resolved_to_local_def = false;
-
-  /* With resolution file in hands, take look into resolutions.
-     We can't just return true for resolved_locally symbols,
-     because dynamic linking might overwrite symbols
-     in shared libraries.  */
-  if (TREE_CODE (exp) == VAR_DECL && TREE_PUBLIC (exp)
-      && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
-    {
-      varpool_node *vnode = varpool_node::get (exp);
-      if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition))
-	resolved_locally = true;
-      if (vnode
-	  && resolution_to_local_definition_p (vnode->resolution))
-	resolved_to_local_def = true;
-    }
-  else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp))
-    {
-      struct cgraph_node *node = cgraph_node::get (exp);
-      if (node
-	  && (resolution_local_p (node->resolution) || node->in_other_partition))
-	resolved_locally = true;
-      if (node
-	  && resolution_to_local_definition_p (node->resolution))
-	resolved_to_local_def = true;
-    }
-
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
-    local_p = true;
+    return true;
+
   /* Weakrefs may not bind locally, even though the weakref itself is always
      static and therefore local.  Similarly, the resolver for ifunc functions
      might resolve to a non-local function.
      FIXME: We can resolve the weakref case more curefuly by looking at the
      weakref alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
 	   || (TREE_CODE (exp) == FUNCTION_DECL
 	       && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
-    local_p = false;
+    return false;
+
   /* Static variables are always local.  */
-  else if (! TREE_PUBLIC (exp))
-    local_p = true;
-  /* A variable is local if the user has said explicitly that it will
-     be.  */
-  else if ((DECL_VISIBILITY_SPECIFIED (exp)
-	    || resolved_to_local_def)
-	   && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
-  /* Variables defined outside this object might not be local.  */
-  else if (DECL_EXTERNAL (exp) && !resolved_locally)
-    local_p = false;
-  /* If defined in this object and visibility is not default, must be
-     local.  */
-  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
-    local_p = true;
-  /* Default visibility weak data can be overridden by a strong symbol
-     in another module and so are not local.  */
-  else if (DECL_WEAK (exp)
-	   && !resolved_locally)
-    local_p = false;
+  if (! TREE_PUBLIC (exp))
+    return true;
+
+  /* With resolution file in hand, take look into resolutions.
+     We can't just return true for resolved_locally symbols,
+     because dynamic linking might overwrite symbols
+     in shared libraries.  */
+  bool resolved_locally = false;
+  bool defined_locally = false;
+  if (symtab_node *node = symtab_node::get (exp))
+    {
+      if (node->definition || node->in_other_partition)
+	{
+	  defined_locally = true;
+	  resolved_locally = (weak_dominate && !shlib);
+	}
+      if (resolution_to_local_definition_p (node->resolution))
+	defined_locally = resolved_locally = true;
+      else if (resolution_local_p (node->resolution))
+	resolved_locally = true;
+    }
+
+  /* Undefined weak symbols are never defined locally.  */
+  if (DECL_WEAK (exp) && !defined_locally)
+    return false;
+
+  /* A symbol is local if the user has said explicitly that it will be,
+     or if we have a definition for the symbol.  We cannot infer visibility
+     for undefined symbols.  */
+  if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT
+      && (DECL_VISIBILITY_SPECIFIED (exp) || defined_locally))
+    return true;
+
   /* If PIC, then assume that any global name can be overridden by
      symbols resolved from other modules.  */
-  else if (shlib)
-    local_p = false;
+  if (shlib)
+    return false;
+
+  /* Variables defined outside this object might not be local.  */
+  if (DECL_EXTERNAL (exp) && !resolved_locally)
+    return false;
+
+  /* Non-dominant weak symbols are not defined locally.  */
+  if (DECL_WEAK (exp) && !resolved_locally)
+    return false;
+
   /* Uninitialized COMMON variable may be unified with symbols
      resolved from other modules.  */
-  else if (DECL_COMMON (exp)
-	   && !resolved_locally
-	   && (DECL_INITIAL (exp) == NULL
-	       || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
-    local_p = false;
+  if (DECL_COMMON (exp)
+      && !resolved_locally
+      && (DECL_INITIAL (exp) == NULL
+	  || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node)))
+    return false;
+
   /* Otherwise we're left with initialized (or non-common) global data
      which is of necessity defined locally.  */
-  else
-    local_p = true;
+  return true;
+}
+
+/* Assume ELF-ish defaults, since that's pretty much the most liberal
+   wrt cross-module name binding.  */
+
+bool
+default_binds_local_p (const_tree exp)
+{
+  return default_binds_local_p_2 (exp, flag_shlib != 0, true);
+}
 
-  return local_p;
+bool
+default_binds_local_p_1 (const_tree exp, int shlib)
+{
+  return default_binds_local_p_2 (exp, shlib != 0, false);
 }
 
 /* Return true when references to DECL must bind to current definition in
@@ -6914,22 +6913,14 @@ decl_binds_to_current_def_p (const_tree decl)
     return false;
   if (!TREE_PUBLIC (decl))
     return true;
+
   /* When resolution is available, just use it.  */
-  if (TREE_CODE (decl) == VAR_DECL
-      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+  if (symtab_node *node = symtab_node::get (decl))
     {
-      varpool_node *vnode = varpool_node::get (decl);
-      if (vnode
-	  && vnode->resolution != LDPR_UNKNOWN)
-	return resolution_to_local_definition_p (vnode->resolution);
-    }
-  else if (TREE_CODE (decl) == FUNCTION_DECL)
-    {
-      struct cgraph_node *node = cgraph_node::get (decl);
-      if (node
-	  && node->resolution != LDPR_UNKNOWN)
+      if (node->resolution != LDPR_UNKNOWN)
 	return resolution_to_local_definition_p (node->resolution);
     }
+
   /* Otherwise we have to assume the worst for DECL_WEAK (hidden weaks
      binds locally but still can be overwritten), DECL_COMMON (can be merged
      with a non-common definition somewhere in the same module) or
@@ -7449,9 +7440,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED,
 {
   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
      set in order to avoid putting out names that are never really
-     used. */
+     used.  Always output visibility specified in the source.  */
   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-      && targetm.binds_local_p (decl))
+      && (DECL_VISIBILITY_SPECIFIED (decl)
+	  || targetm.binds_local_p (decl)))
     maybe_assemble_visibility (decl);
 }
 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-13  0:05                                 ` Richard Henderson
@ 2015-02-13  4:14                                   ` H.J. Lu
  2015-02-13  5:11                                     ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-13  4:14 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

On Thu, Feb 12, 2015 at 4:04 PM, Richard Henderson <rth@redhat.com> wrote:
> On 02/12/2015 03:05 PM, H.J. Lu wrote:
>> @@ -6830,9 +6830,15 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate)
>>    bool resolved_locally = false;
>>    if (symtab_node *node = symtab_node::get (exp))
>>      {
>> -      /* When not building shared library and weak_dominate is true:
>> -         weak, common or initialized symbols are resolved locally.  */
>> -      if ((weak_dominate && !shlib && node->definition)
>> +      /* When weak_dominate is true and not building shared library or
>> +      non-default visibility is specified by user: weak, common or
>> +      initialized symbols are resolved locally.
>> +      */
>> +      if (((!shlib
>> +         || (DECL_VISIBILITY_SPECIFIED (exp)
>> +             && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT))
>> +        && weak_dominate
>> +        && node->definition)
>>         || node->in_other_partition
>>         || resolution_local_p (node->resolution))
>>       resolved_locally = true;
>
> Hum.  I don't find that particularly easy to reason with either.
>
> How about this?  I'm about half-way through regression testing on it.
>
> I re-instated the use of resolution_to_local_definition_p, and attempt to infer
> a proper value for that when lto isn't in use.  I use this to eliminate only
> undef-weak early, rather than non-dominate weak.
>
> I re-instated the use of the existence of the local definition in the
> DECL_VISIBILITY test.  But unlike before, I reason that this allows us to
> eliminate the second visibility check.  We either have an assertion from the
> user (SPECIFIED), or we know we have a definition.  We no longer rely on the
> DECL_EXTERNAL test in the middle eliminating symbols without a definition.
>
> I shuffled some of the "return false" tests around among themselves, attempting
> to put the simplest test first.  No change in behavior there.
>
> (First patch is delta from the 5-patch bundle; second patch is the
> composite from trunk, to avoid confusion.)
>
>

I tried the second patch.  Results look good on Linux/x86-64.

Thanks.


-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-13  4:14                                   ` H.J. Lu
@ 2015-02-13  5:11                                     ` Richard Henderson
  2015-02-18 14:17                                       ` Alex Velenko
  0 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2015-02-13  5:11 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

On 02/12/2015 08:14 PM, H.J. Lu wrote:
> I tried the second patch.  Results look good on Linux/x86-64.

Thanks.  My results concurr.  I went ahead and installed the patch as posted.


r~


2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
            Richard Henderson  <rth@redhat.com>

        PR rtl/32219
        * cgraphunit.c (cgraph_node::finalize_function): Set definition
        before notice_global_symbol.
        (varpool_node::finalize_decl): Likewise.
        * varasm.c (default_binds_local_p_2): Rename from
        default_binds_local_p_1, add weak_dominate argument.  Use direct
        returns instead of assigning to local variable.  Unify varpool and
        cgraph paths via symtab_node.  Reject undef weak variables before
        testing visibility.  Reorder tests for simplicity.
        (default_binds_local_p): Use default_binds_local_p_2.
        (default_binds_local_p_1): Likewise.
        (decl_binds_to_current_def_p): Unify varpool and cgraph paths
        via symtab_node.
        (default_elf_asm_output_external): Emit visibility when specified.

2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>

        PR rtl/32219
        * gcc.dg/visibility-22.c: New test.
        * gcc.dg/visibility-23.c: New test.
        * gcc.target/i386/pr32219-1.c: New test.
        * gcc.target/i386/pr32219-2.c: New test.
        * gcc.target/i386/pr32219-3.c: New test.
        * gcc.target/i386/pr32219-4.c: New test.
        * gcc.target/i386/pr32219-5.c: New test.
        * gcc.target/i386/pr32219-6.c: New test.
        * gcc.target/i386/pr32219-7.c: New test.
        * gcc.target/i386/pr32219-8.c: New test.
        * gcc.target/i386/pr64317.c: Expect GOTOFF, not GOT.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-13  5:11                                     ` Richard Henderson
@ 2015-02-18 14:17                                       ` Alex Velenko
  2015-02-19 13:12                                         ` H.J. Lu
  2015-02-19 15:02                                         ` Richard Henderson
  0 siblings, 2 replies; 53+ messages in thread
From: Alex Velenko @ 2015-02-18 14:17 UTC (permalink / raw)
  To: Richard Henderson, H.J. Lu
  Cc: Jack Howarth, GCC Patches, Mike Stump, Iain Sandoe, Jan Hubicka

On 13/02/15 05:11, Richard Henderson wrote:
> On 02/12/2015 08:14 PM, H.J. Lu wrote:
>> I tried the second patch.  Results look good on Linux/x86-64.
>
> Thanks.  My results concurr.  I went ahead and installed the patch as posted.
>
>
> r~
>
>
> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>              Richard Henderson  <rth@redhat.com>
>
>          PR rtl/32219
>          * cgraphunit.c (cgraph_node::finalize_function): Set definition
>          before notice_global_symbol.
>          (varpool_node::finalize_decl): Likewise.
>          * varasm.c (default_binds_local_p_2): Rename from
>          default_binds_local_p_1, add weak_dominate argument.  Use direct
>          returns instead of assigning to local variable.  Unify varpool and
>          cgraph paths via symtab_node.  Reject undef weak variables before
>          testing visibility.  Reorder tests for simplicity.
>          (default_binds_local_p): Use default_binds_local_p_2.
>          (default_binds_local_p_1): Likewise.
>          (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>          via symtab_node.
>          (default_elf_asm_output_external): Emit visibility when specified.
>
> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>
>          PR rtl/32219
>          * gcc.dg/visibility-22.c: New test.
>          * gcc.dg/visibility-23.c: New test.
>          * gcc.target/i386/pr32219-1.c: New test.
>          * gcc.target/i386/pr32219-2.c: New test.
>          * gcc.target/i386/pr32219-3.c: New test.
>          * gcc.target/i386/pr32219-4.c: New test.
>          * gcc.target/i386/pr32219-5.c: New test.
>          * gcc.target/i386/pr32219-6.c: New test.
>          * gcc.target/i386/pr32219-7.c: New test.
>          * gcc.target/i386/pr32219-8.c: New test.
>          * gcc.target/i386/pr64317.c: Expect GOTOFF, not GOT.
>

Hi all,
By changing behaviour of varasm.c:default_binds_local_p, this patch 
changes behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and 
through it breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols.

As a result, I get regression for gcc.target/arm/long-calls-1.c on
arm-none-eabi:
FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n
FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n

In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there
is a description for -mlong-calls.

This has to be fixed.

Kind regards,
Alex

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-18 14:17                                       ` Alex Velenko
@ 2015-02-19 13:12                                         ` H.J. Lu
  2015-02-19 15:02                                         ` Richard Henderson
  1 sibling, 0 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-19 13:12 UTC (permalink / raw)
  To: Alex Velenko
  Cc: Richard Henderson, Jack Howarth, GCC Patches, Mike Stump,
	Iain Sandoe, Jan Hubicka

On Wed, Feb 18, 2015 at 6:17 AM, Alex Velenko <Alex.Velenko@arm.com> wrote:
> On 13/02/15 05:11, Richard Henderson wrote:
>>
>> On 02/12/2015 08:14 PM, H.J. Lu wrote:
>>>
>>> I tried the second patch.  Results look good on Linux/x86-64.
>>
>>
>> Thanks.  My results concurr.  I went ahead and installed the patch as
>> posted.
>>
>>
>> r~
>>
>>
>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>              Richard Henderson  <rth@redhat.com>
>>
>>          PR rtl/32219
>>          * cgraphunit.c (cgraph_node::finalize_function): Set definition
>>          before notice_global_symbol.
>>          (varpool_node::finalize_decl): Likewise.
>>          * varasm.c (default_binds_local_p_2): Rename from
>>          default_binds_local_p_1, add weak_dominate argument.  Use direct
>>          returns instead of assigning to local variable.  Unify varpool
>> and
>>          cgraph paths via symtab_node.  Reject undef weak variables before
>>          testing visibility.  Reorder tests for simplicity.
>>          (default_binds_local_p): Use default_binds_local_p_2.
>>          (default_binds_local_p_1): Likewise.
>>          (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>>          via symtab_node.
>>          (default_elf_asm_output_external): Emit visibility when
>> specified.
>>
>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>          PR rtl/32219
>>          * gcc.dg/visibility-22.c: New test.
>>          * gcc.dg/visibility-23.c: New test.
>>          * gcc.target/i386/pr32219-1.c: New test.
>>          * gcc.target/i386/pr32219-2.c: New test.
>>          * gcc.target/i386/pr32219-3.c: New test.
>>          * gcc.target/i386/pr32219-4.c: New test.
>>          * gcc.target/i386/pr32219-5.c: New test.
>>          * gcc.target/i386/pr32219-6.c: New test.
>>          * gcc.target/i386/pr32219-7.c: New test.
>>          * gcc.target/i386/pr32219-8.c: New test.
>>          * gcc.target/i386/pr64317.c: Expect GOTOFF, not GOT.
>>
>
> Hi all,
> By changing behaviour of varasm.c:default_binds_local_p, this patch changes
> behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and through it
> breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols.
>
> As a result, I get regression for gcc.target/arm/long-calls-1.c on
> arm-none-eabi:
> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n
> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n
>
> In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there
> is a description for -mlong-calls.

I know nothing about arm.  I built a cross compiler and got:

[hjl@gnu-tools-1 gcc]$ cat /tmp/z.i
const char *
__attribute__((long_call)) __attribute__((noinline))
strong_l1 (void) { return "strong_l1"; }
const char * call_strong_l1 (void) { return strong_l1 () + 1; }
const char * sibcall_strong_l1 (void) { return strong_l1 (); }
const char *
__attribute__((weak)) __attribute__((long_call)) __attribute__((noinline))
weak_l1 (void) { return "weak_l1"; }
const char * call_weak_l1 (void) { return weak_l1 () + 1; }
const char * sibcall_weak_l1 (void) { return weak_l1 (); }
[hjl@gnu-tools-1 gcc]$ ./xgcc -B./ -S -O2 /tmp/z.i
[hjl@gnu-tools-1 gcc]$ grep "b.*        strong_l1" z.s
.global strong_l1
bl strong_l1
b strong_l1
[hjl@gnu-tools-1 gcc]$ grep "b.*        weak_l1" z.s
bl weak_l1
bl weak_l1
[hjl@gnu-tools-1 gcc]$

Can someone tell me what is wrong with the output and why?

-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-18 14:17                                       ` Alex Velenko
  2015-02-19 13:12                                         ` H.J. Lu
@ 2015-02-19 15:02                                         ` Richard Henderson
  2015-02-19 17:25                                           ` Alex Velenko
  1 sibling, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2015-02-19 15:02 UTC (permalink / raw)
  To: Alex Velenko, H.J. Lu
  Cc: Jack Howarth, GCC Patches, Ramana Radhakrishnan, Jan Hubicka

On 02/18/2015 06:17 AM, Alex Velenko wrote:
> By changing behaviour of varasm.c:default_binds_local_p, this patch changes
> behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and through it
> breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols.
> 
> As a result, I get regression for gcc.target/arm/long-calls-1.c on
> arm-none-eabi:
> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n
> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n
> 
> In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there
> is a description for -mlong-calls.
> 
> This has to be fixed.

Please file a bug, for tracking purposes.

That said, it looks as if arm_function_in_section_p should be using
decl_binds_to_current_def_p instead of targetm.binds_local_p.

That will properly reject weak symbols within a given module until we receive
extra information from LTO indicating when a weak definition turns out to be
the prevailing definition.


r~

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 15:02                                         ` Richard Henderson
@ 2015-02-19 17:25                                           ` Alex Velenko
  2015-02-19 17:27                                             ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: Alex Velenko @ 2015-02-19 17:25 UTC (permalink / raw)
  To: Richard Henderson, H.J. Lu
  Cc: Jack Howarth, GCC Patches, Ramana Radhakrishnan, Jan Hubicka

On 19/02/15 14:16, Richard Henderson wrote:
> On 02/18/2015 06:17 AM, Alex Velenko wrote:
>> By changing behaviour of varasm.c:default_binds_local_p, this patch changes
>> behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and through it
>> breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols.
>>
>> As a result, I get regression for gcc.target/arm/long-calls-1.c on
>> arm-none-eabi:
>> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n
>> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n
>>
>> In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there
>> is a description for -mlong-calls.
>>
>> This has to be fixed.
>
> Please file a bug, for tracking purposes.
>
> That said, it looks as if arm_function_in_section_p should be using
> decl_binds_to_current_def_p instead of targetm.binds_local_p.
>
> That will properly reject weak symbols within a given module until we receive
> extra information from LTO indicating when a weak definition turns out to be
> the prevailing definition.
>
>
> r~
>

Hi Richard,
Thank you for your reply.
Here is the bug report.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65121

Your suggestion seem to fix gcc.target/arm/long-calls-1.c, but has to be 
thoroughly tested.

Kind regards,
Alex

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 17:25                                           ` Alex Velenko
@ 2015-02-19 17:27                                             ` Richard Henderson
  2015-03-03 15:58                                               ` Alex Velenko
  0 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2015-02-19 17:27 UTC (permalink / raw)
  To: Alex Velenko
  Cc: H.J. Lu, Jack Howarth, GCC Patches, Ramana Radhakrishnan, Jan Hubicka

On 02/19/2015 09:08 AM, Alex Velenko wrote:
> Your suggestion seem to fix gcc.target/arm/long-calls-1.c, but has to be
> thoroughly tested.

Before you do complete testing, please also delete the TREE_STATIC test.
That bit should never be relevant to functions, as it indicates not that
it is in the compilation unit, but that it has static (as opposed to
automatic) storage duration.  Thus it is only relevant to variables.


r~



diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 7bf5b4d..777230e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6392,14 +6392,8 @@ arm_set_default_type_attributes (tree type)
 static bool
 arm_function_in_section_p (tree decl, section *section)
 {
-  /* We can only be certain about functions defined in the same
-     compilation unit.  */
-  if (!TREE_STATIC (decl))
-    return false;
-
-  /* Make sure that SYMBOL always binds to the definition in this
-     compilation unit.  */
-  if (!targetm.binds_local_p (decl))
+  /* We can only be certain about the prevailing symbol definition.  */
+  if (!decl_binds_to_current_def_p (decl))
     return false;

   /* If DECL_SECTION_NAME is set, assume it is trustworthy.  */

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 17:27                                             ` Richard Henderson
@ 2015-03-03 15:58                                               ` Alex Velenko
  2015-03-05 14:55                                                 ` Alex Velenko
  0 siblings, 1 reply; 53+ messages in thread
From: Alex Velenko @ 2015-03-03 15:58 UTC (permalink / raw)
  To: Richard Henderson
  Cc: H.J. Lu, Jack Howarth, GCC Patches, Ramana Radhakrishnan, Jan Hubicka

On 19/02/15 17:26, Richard Henderson wrote:
> On 02/19/2015 09:08 AM, Alex Velenko wrote:
>> Your suggestion seem to fix gcc.target/arm/long-calls-1.c, but has to be
>> thoroughly tested.
>
> Before you do complete testing, please also delete the TREE_STATIC test.
> That bit should never be relevant to functions, as it indicates not that
> it is in the compilation unit, but that it has static (as opposed to
> automatic) storage duration.  Thus it is only relevant to variables.
>
>
> r~
>
>
>
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index 7bf5b4d..777230e 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -6392,14 +6392,8 @@ arm_set_default_type_attributes (tree type)
>   static bool
>   arm_function_in_section_p (tree decl, section *section)
>   {
> -  /* We can only be certain about functions defined in the same
> -     compilation unit.  */
> -  if (!TREE_STATIC (decl))
> -    return false;
> -
> -  /* Make sure that SYMBOL always binds to the definition in this
> -     compilation unit.  */
> -  if (!targetm.binds_local_p (decl))
> +  /* We can only be certain about the prevailing symbol definition.  */
> +  if (!decl_binds_to_current_def_p (decl))
>       return false;
>
>     /* If DECL_SECTION_NAME is set, assume it is trustworthy.  */
>
>

Hi,

Did a bootstrap and a full regression run on arm-none-linux-gnueabihf,
No new regressions found. Some previously failing tests in libstdc++ 
started to fail differently, for example:

< ERROR: 22_locale/num_get/get/wchar_t/2.cc: can't read 
"additional_sources": no such variable for " dg-do 22 run { xfail 
lax_strtof\
p } "
< UNRESOLVED: 22_locale/num_get/get/wchar_t/2.cc: can't read 
"additional_sources": no such variable for " dg-do 22 run { xfail lax_s\
trtofp } "
---
 > ERROR: 22_locale/num_get/get/wchar_t/2.cc: can't read 
"et_cache(uclibc,value)": no such element in array for " dg-do 22 run { 
xfai\
l lax_strtofp } "
 > UNRESOLVED: 22_locale/num_get/get/wchar_t/2.cc: can't read 
"et_cache(uclibc,value)": no such element in array for " dg-do 22 run {\
  xfail lax_strtofp } "


But I think it is okay.

Kind regards,
Alex

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-03-03 15:58                                               ` Alex Velenko
@ 2015-03-05 14:55                                                 ` Alex Velenko
  2015-03-05 15:31                                                   ` Ramana Radhakrishnan
  0 siblings, 1 reply; 53+ messages in thread
From: Alex Velenko @ 2015-03-05 14:55 UTC (permalink / raw)
  To: Richard Henderson
  Cc: H.J. Lu, Jack Howarth, GCC Patches, Ramana Radhakrishnan, Jan Hubicka


On 03/03/15 15:58, Alex Velenko wrote:
> On 19/02/15 17:26, Richard Henderson wrote:
>> On 02/19/2015 09:08 AM, Alex Velenko wrote:
>>> Your suggestion seem to fix gcc.target/arm/long-calls-1.c, but has 
>>> to be
>>> thoroughly tested.
>>
>> Before you do complete testing, please also delete the TREE_STATIC test.
>> That bit should never be relevant to functions, as it indicates not that
>> it is in the compilation unit, but that it has static (as opposed to
>> automatic) storage duration.  Thus it is only relevant to variables.
>>
>>
>> r~
>>
>>
>>
>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>> index 7bf5b4d..777230e 100644
>> --- a/gcc/config/arm/arm.c
>> +++ b/gcc/config/arm/arm.c
>> @@ -6392,14 +6392,8 @@ arm_set_default_type_attributes (tree type)
>>   static bool
>>   arm_function_in_section_p (tree decl, section *section)
>>   {
>> -  /* We can only be certain about functions defined in the same
>> -     compilation unit.  */
>> -  if (!TREE_STATIC (decl))
>> -    return false;
>> -
>> -  /* Make sure that SYMBOL always binds to the definition in this
>> -     compilation unit.  */
>> -  if (!targetm.binds_local_p (decl))
>> +  /* We can only be certain about the prevailing symbol definition.  */
>> +  if (!decl_binds_to_current_def_p (decl))
>>       return false;
>>
>>     /* If DECL_SECTION_NAME is set, assume it is trustworthy. */
>>
>>
>
> Hi,
>
> Did a bootstrap and a full regression run on arm-none-linux-gnueabihf,
> No new regressions found. Some previously failing tests in libstdc++ 
> started to fail differently, for example:
>
> < ERROR: 22_locale/num_get/get/wchar_t/2.cc: can't read 
> "additional_sources": no such variable for " dg-do 22 run { xfail 
> lax_strtof\
> p } "
> < UNRESOLVED: 22_locale/num_get/get/wchar_t/2.cc: can't read 
> "additional_sources": no such variable for " dg-do 22 run { xfail lax_s\
> trtofp } "
> ---
> > ERROR: 22_locale/num_get/get/wchar_t/2.cc: can't read 
> "et_cache(uclibc,value)": no such element in array for " dg-do 22 run 
> { xfai\
> l lax_strtofp } "
> > UNRESOLVED: 22_locale/num_get/get/wchar_t/2.cc: can't read 
> "et_cache(uclibc,value)": no such element in array for " dg-do 22 run {\
>  xfail lax_strtofp } "
>
>
> But I think it is okay.
>
> Kind regards,
> Alex
>
>

Hi,
Ping. Could someone, please approve Richard's patch?
This issue needs fixing.
Kind regards,
Alex

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-03-05 14:55                                                 ` Alex Velenko
@ 2015-03-05 15:31                                                   ` Ramana Radhakrishnan
  2015-03-06 11:14                                                     ` Alex Velenko
  0 siblings, 1 reply; 53+ messages in thread
From: Ramana Radhakrishnan @ 2015-03-05 15:31 UTC (permalink / raw)
  To: Alex Velenko, Richard Henderson
  Cc: H.J. Lu, Jack Howarth, GCC Patches, Ramana Radhakrishnan, Jan Hubicka


>>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>>> index 7bf5b4d..777230e 100644
>>> --- a/gcc/config/arm/arm.c
>>> +++ b/gcc/config/arm/arm.c
>>> @@ -6392,14 +6392,8 @@ arm_set_default_type_attributes (tree type)
>>>   static bool
>>>   arm_function_in_section_p (tree decl, section *section)
>>>   {
>>> -  /* We can only be certain about functions defined in the same
>>> -     compilation unit.  */
>>> -  if (!TREE_STATIC (decl))
>>> -    return false;
>>> -
>>> -  /* Make sure that SYMBOL always binds to the definition in this
>>> -     compilation unit.  */
>>> -  if (!targetm.binds_local_p (decl))
>>> +  /* We can only be certain about the prevailing symbol definition.  */
>>> +  if (!decl_binds_to_current_def_p (decl))
>>>       return false;
>>>
>>>     /* If DECL_SECTION_NAME is set, assume it is trustworthy. */
>>>
>>>


Sorry to have missed this - I've also been traveling recently which has 
made it harder with patch traffic - this is OK if no regressions.

Please apply with an appropriate Changelog.

regressions
Ramana

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-03-05 15:31                                                   ` Ramana Radhakrishnan
@ 2015-03-06 11:14                                                     ` Alex Velenko
  0 siblings, 0 replies; 53+ messages in thread
From: Alex Velenko @ 2015-03-06 11:14 UTC (permalink / raw)
  To: Ramana Radhakrishnan, Richard Henderson
  Cc: H.J. Lu, Jack Howarth, GCC Patches, Jan Hubicka


On 05/03/15 15:28, Ramana Radhakrishnan wrote:
>>>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>>>> index 7bf5b4d..777230e 100644
>>>> --- a/gcc/config/arm/arm.c
>>>> +++ b/gcc/config/arm/arm.c
>>>> @@ -6392,14 +6392,8 @@ arm_set_default_type_attributes (tree type)
>>>>    static bool
>>>>    arm_function_in_section_p (tree decl, section *section)
>>>>    {
>>>> -  /* We can only be certain about functions defined in the same
>>>> -     compilation unit.  */
>>>> -  if (!TREE_STATIC (decl))
>>>> -    return false;
>>>> -
>>>> -  /* Make sure that SYMBOL always binds to the definition in this
>>>> -     compilation unit.  */
>>>> -  if (!targetm.binds_local_p (decl))
>>>> +  /* We can only be certain about the prevailing symbol definition.  */
>>>> +  if (!decl_binds_to_current_def_p (decl))
>>>>        return false;
>>>>
>>>>      /* If DECL_SECTION_NAME is set, assume it is trustworthy. */
>>>>
>>>>
>
> Sorry to have missed this - I've also been traveling recently which has
> made it harder with patch traffic - this is OK if no regressions.
>
> Please apply with an appropriate Changelog.
>
> regressions
> Ramana
>
>
Hi,
Committed as r221220 and fixed ChangeLog entry in r221234.
Sorry for claiming the patch for myself.
Kind regards,
Alex

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 21:43         ` H.J. Lu
@ 2015-02-19 23:39           ` Uros Bizjak
  0 siblings, 0 replies; 53+ messages in thread
From: Uros Bizjak @ 2015-02-19 23:39 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Richard Henderson, gcc-patches

On Thu, Feb 19, 2015 at 10:35 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Feb 19, 2015 at 1:16 PM, Richard Henderson <rth@redhat.com> wrote:
>> On 02/19/2015 01:04 PM, Uros Bizjak wrote:
>>> 2015-02-19  Uros Bizjak  <ubizjak@gmail.com>
>>>
>>>     * config/alpha/alpha.c (alpha_in_small_data_p): Reject common symbols.
>>
>> Ok.  Thanks.
>
> We tried it on ia64 and failed with Ada build.

As I see from the PR, it was the pilot error, please see comment #14 [1].

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064#c14

Uros.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 21:35       ` Richard Henderson
@ 2015-02-19 21:43         ` H.J. Lu
  2015-02-19 23:39           ` Uros Bizjak
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-19 21:43 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Uros Bizjak, gcc-patches

On Thu, Feb 19, 2015 at 1:16 PM, Richard Henderson <rth@redhat.com> wrote:
> On 02/19/2015 01:04 PM, Uros Bizjak wrote:
>> 2015-02-19  Uros Bizjak  <ubizjak@gmail.com>
>>
>>     * config/alpha/alpha.c (alpha_in_small_data_p): Reject common symbols.
>
> Ok.  Thanks.

We tried it on ia64 and failed with Ada build.

-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 21:07     ` Uros Bizjak
  2015-02-19 21:08       ` H.J. Lu
@ 2015-02-19 21:35       ` Richard Henderson
  2015-02-19 21:43         ` H.J. Lu
  1 sibling, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2015-02-19 21:35 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: H.J. Lu, gcc-patches

On 02/19/2015 01:04 PM, Uros Bizjak wrote:
> 2015-02-19  Uros Bizjak  <ubizjak@gmail.com>
> 
>     * config/alpha/alpha.c (alpha_in_small_data_p): Reject common symbols.

Ok.  Thanks.


r~

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 21:08       ` H.J. Lu
  2015-02-19 21:16         ` H.J. Lu
@ 2015-02-19 21:16         ` Richard Henderson
  1 sibling, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2015-02-19 21:16 UTC (permalink / raw)
  To: H.J. Lu, Uros Bizjak; +Cc: gcc-patches

On 02/19/2015 01:07 PM, H.J. Lu wrote:
>> > The attached patch fixes all alpha-linux-gnu failures.
>> >
>> > 2015-02-19  Uros Bizjak  <ubizjak@gmail.com>
>> >
>> >     * config/alpha/alpha.c (alpha_in_small_data_p): Reject common symbols.
>> >
>> > Patch was bootstrapped and regression tested on alphaev68-linux-gnu.
>> >
>> > OK for mainline?
>> >
> You may want to use something like this:
> 
> https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01105.html

That's exactly what he's done.


r~

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 21:08       ` H.J. Lu
@ 2015-02-19 21:16         ` H.J. Lu
  2015-02-19 21:16         ` Richard Henderson
  1 sibling, 0 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-19 21:16 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: Richard Henderson, gcc-patches

On Thu, Feb 19, 2015 at 1:07 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Feb 19, 2015 at 1:04 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Mon, Feb 16, 2015 at 5:30 PM, Richard Henderson <rth@redhat.com> wrote:
>>
>>>>>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>>>>>             Richard Henderson  <rth@redhat.com>
>>>>>>
>>>>>>         PR rtl/32219
>>>>>>         * cgraphunit.c (cgraph_node::finalize_function): Set definition
>>>>>>         before notice_global_symbol.
>>>>>>         (varpool_node::finalize_decl): Likewise.
>>>>>>         * varasm.c (default_binds_local_p_2): Rename from
>>>>>>         default_binds_local_p_1, add weak_dominate argument.  Use direct
>>>>>>         returns instead of assigning to local variable.  Unify varpool and
>>>>>>         cgraph paths via symtab_node.  Reject undef weak variables before
>>>>>>         testing visibility.  Reorder tests for simplicity.
>>>>>>         (default_binds_local_p): Use default_binds_local_p_2.
>>>>>>         (default_binds_local_p_1): Likewise.
>>>>>>         (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>>>>>>         via symtab_node.
>>>>>>         (default_elf_asm_output_external): Emit visibility when specified.
>>>>>
>>>>> It looks like this patch broke alphaev68-linux-gnu [1]. There are many
>>>>> failures of the type:
>>>>>
>>>>> /tmp/cck7V7MR.o: In function
>>>>> `__static_initialization_and_destruction_0(int, int)':^M
>>>>> (.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
>>>>> `std::__cxx11::basic_string<char, std::char_traits<char>,
>>>>> std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
>>>>> .text section in
>>>>> /space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
>>>>> /space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
>>>>> relocation against dynamic symbol
>>>>
>>>> It could be related to:
>>>>
>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064
>>>>
>>>> Before this bug fix, all common symbols don't bind locally,
>>>> which is one of PR 32219 bugs.  After this fix, common
>>>> symbols bind locally.  It may cause problems on targets with
>>>> small data sections and common symbols aren't in small
>>>> data section:
>>>
>>> This is a destructor, and so obviously not a common symbol.
>>>
>>> I'll have a look.
>>
>> The attached patch fixes all alpha-linux-gnu failures.
>>
>> 2015-02-19  Uros Bizjak  <ubizjak@gmail.com>
>>
>>     * config/alpha/alpha.c (alpha_in_small_data_p): Reject common symbols.
>>
>> Patch was bootstrapped and regression tested on alphaev68-linux-gnu.
>>
>> OK for mainline?
>>
>
> You may want to use something like this:
>
> https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01105.html
>

See:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064

for why.

-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-19 21:07     ` Uros Bizjak
@ 2015-02-19 21:08       ` H.J. Lu
  2015-02-19 21:16         ` H.J. Lu
  2015-02-19 21:16         ` Richard Henderson
  2015-02-19 21:35       ` Richard Henderson
  1 sibling, 2 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-19 21:08 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: Richard Henderson, gcc-patches

On Thu, Feb 19, 2015 at 1:04 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Mon, Feb 16, 2015 at 5:30 PM, Richard Henderson <rth@redhat.com> wrote:
>
>>>>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>>>>             Richard Henderson  <rth@redhat.com>
>>>>>
>>>>>         PR rtl/32219
>>>>>         * cgraphunit.c (cgraph_node::finalize_function): Set definition
>>>>>         before notice_global_symbol.
>>>>>         (varpool_node::finalize_decl): Likewise.
>>>>>         * varasm.c (default_binds_local_p_2): Rename from
>>>>>         default_binds_local_p_1, add weak_dominate argument.  Use direct
>>>>>         returns instead of assigning to local variable.  Unify varpool and
>>>>>         cgraph paths via symtab_node.  Reject undef weak variables before
>>>>>         testing visibility.  Reorder tests for simplicity.
>>>>>         (default_binds_local_p): Use default_binds_local_p_2.
>>>>>         (default_binds_local_p_1): Likewise.
>>>>>         (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>>>>>         via symtab_node.
>>>>>         (default_elf_asm_output_external): Emit visibility when specified.
>>>>
>>>> It looks like this patch broke alphaev68-linux-gnu [1]. There are many
>>>> failures of the type:
>>>>
>>>> /tmp/cck7V7MR.o: In function
>>>> `__static_initialization_and_destruction_0(int, int)':^M
>>>> (.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
>>>> `std::__cxx11::basic_string<char, std::char_traits<char>,
>>>> std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
>>>> .text section in
>>>> /space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
>>>> /space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
>>>> relocation against dynamic symbol
>>>
>>> It could be related to:
>>>
>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064
>>>
>>> Before this bug fix, all common symbols don't bind locally,
>>> which is one of PR 32219 bugs.  After this fix, common
>>> symbols bind locally.  It may cause problems on targets with
>>> small data sections and common symbols aren't in small
>>> data section:
>>
>> This is a destructor, and so obviously not a common symbol.
>>
>> I'll have a look.
>
> The attached patch fixes all alpha-linux-gnu failures.
>
> 2015-02-19  Uros Bizjak  <ubizjak@gmail.com>
>
>     * config/alpha/alpha.c (alpha_in_small_data_p): Reject common symbols.
>
> Patch was bootstrapped and regression tested on alphaev68-linux-gnu.
>
> OK for mainline?
>

You may want to use something like this:

https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01105.html


-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-16 16:30   ` Richard Henderson
  2015-02-16 16:38     ` H.J. Lu
@ 2015-02-19 21:07     ` Uros Bizjak
  2015-02-19 21:08       ` H.J. Lu
  2015-02-19 21:35       ` Richard Henderson
  1 sibling, 2 replies; 53+ messages in thread
From: Uros Bizjak @ 2015-02-19 21:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: H.J. Lu, gcc-patches

On Mon, Feb 16, 2015 at 5:30 PM, Richard Henderson <rth@redhat.com> wrote:

>>>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>>>             Richard Henderson  <rth@redhat.com>
>>>>
>>>>         PR rtl/32219
>>>>         * cgraphunit.c (cgraph_node::finalize_function): Set definition
>>>>         before notice_global_symbol.
>>>>         (varpool_node::finalize_decl): Likewise.
>>>>         * varasm.c (default_binds_local_p_2): Rename from
>>>>         default_binds_local_p_1, add weak_dominate argument.  Use direct
>>>>         returns instead of assigning to local variable.  Unify varpool and
>>>>         cgraph paths via symtab_node.  Reject undef weak variables before
>>>>         testing visibility.  Reorder tests for simplicity.
>>>>         (default_binds_local_p): Use default_binds_local_p_2.
>>>>         (default_binds_local_p_1): Likewise.
>>>>         (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>>>>         via symtab_node.
>>>>         (default_elf_asm_output_external): Emit visibility when specified.
>>>
>>> It looks like this patch broke alphaev68-linux-gnu [1]. There are many
>>> failures of the type:
>>>
>>> /tmp/cck7V7MR.o: In function
>>> `__static_initialization_and_destruction_0(int, int)':^M
>>> (.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
>>> `std::__cxx11::basic_string<char, std::char_traits<char>,
>>> std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
>>> .text section in
>>> /space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
>>> /space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
>>> relocation against dynamic symbol
>>
>> It could be related to:
>>
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064
>>
>> Before this bug fix, all common symbols don't bind locally,
>> which is one of PR 32219 bugs.  After this fix, common
>> symbols bind locally.  It may cause problems on targets with
>> small data sections and common symbols aren't in small
>> data section:
>
> This is a destructor, and so obviously not a common symbol.
>
> I'll have a look.

The attached patch fixes all alpha-linux-gnu failures.

2015-02-19  Uros Bizjak  <ubizjak@gmail.com>

    * config/alpha/alpha.c (alpha_in_small_data_p): Reject common symbols.

Patch was bootstrapped and regression tested on alphaev68-linux-gnu.

OK for mainline?

Uros.

Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c        (revision 220806)
+++ config/alpha/alpha.c        (working copy)
@@ -835,6 +835,10 @@ alpha_in_small_data_p (const_tree exp)
   if (TREE_CODE (exp) == FUNCTION_DECL)
     return false;

+  /* COMMON symbols are never small data.  */
+  if (TREE_CODE (exp) == VAR_DECL && DECL_COMMON (exp))
+    return false;
+
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
       const char *section = DECL_SECTION_NAME (exp);

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-16 16:30   ` Richard Henderson
@ 2015-02-16 16:38     ` H.J. Lu
  2015-02-19 21:07     ` Uros Bizjak
  1 sibling, 0 replies; 53+ messages in thread
From: H.J. Lu @ 2015-02-16 16:38 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Uros Bizjak, gcc-patches

On Mon, Feb 16, 2015 at 8:30 AM, Richard Henderson <rth@redhat.com> wrote:
> On 02/16/2015 06:01 AM, H.J. Lu wrote:
>> On Mon, Feb 16, 2015 at 5:25 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>> Hello!
>>>
>>>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>>>             Richard Henderson  <rth@redhat.com>
>>>>
>>>>         PR rtl/32219
>>>>         * cgraphunit.c (cgraph_node::finalize_function): Set definition
>>>>         before notice_global_symbol.
>>>>         (varpool_node::finalize_decl): Likewise.
>>>>         * varasm.c (default_binds_local_p_2): Rename from
>>>>         default_binds_local_p_1, add weak_dominate argument.  Use direct
>>>>         returns instead of assigning to local variable.  Unify varpool and
>>>>         cgraph paths via symtab_node.  Reject undef weak variables before
>>>>         testing visibility.  Reorder tests for simplicity.
>>>>         (default_binds_local_p): Use default_binds_local_p_2.
>>>>         (default_binds_local_p_1): Likewise.
>>>>         (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>>>>         via symtab_node.
>>>>         (default_elf_asm_output_external): Emit visibility when specified.
>>>
>>> It looks like this patch broke alphaev68-linux-gnu [1]. There are many
>>> failures of the type:
>>>
>>> /tmp/cck7V7MR.o: In function
>>> `__static_initialization_and_destruction_0(int, int)':^M
>>> (.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
>>> `std::__cxx11::basic_string<char, std::char_traits<char>,
>>> std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
>>> .text section in
>>> /space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
>>> /space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
>>> relocation against dynamic symbol
>>
>> It could be related to:
>>
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064
>>
>> Before this bug fix, all common symbols don't bind locally,
>> which is one of PR 32219 bugs.  After this fix, common
>> symbols bind locally.  It may cause problems on targets with
>> small data sections and common symbols aren't in small
>> data section:
>
> This is a destructor, and so obviously not a common symbol.

Then it could be:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65074


-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-16 14:01 ` H.J. Lu
@ 2015-02-16 16:30   ` Richard Henderson
  2015-02-16 16:38     ` H.J. Lu
  2015-02-19 21:07     ` Uros Bizjak
  0 siblings, 2 replies; 53+ messages in thread
From: Richard Henderson @ 2015-02-16 16:30 UTC (permalink / raw)
  To: H.J. Lu, Uros Bizjak; +Cc: gcc-patches

On 02/16/2015 06:01 AM, H.J. Lu wrote:
> On Mon, Feb 16, 2015 at 5:25 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> Hello!
>>
>>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>>             Richard Henderson  <rth@redhat.com>
>>>
>>>         PR rtl/32219
>>>         * cgraphunit.c (cgraph_node::finalize_function): Set definition
>>>         before notice_global_symbol.
>>>         (varpool_node::finalize_decl): Likewise.
>>>         * varasm.c (default_binds_local_p_2): Rename from
>>>         default_binds_local_p_1, add weak_dominate argument.  Use direct
>>>         returns instead of assigning to local variable.  Unify varpool and
>>>         cgraph paths via symtab_node.  Reject undef weak variables before
>>>         testing visibility.  Reorder tests for simplicity.
>>>         (default_binds_local_p): Use default_binds_local_p_2.
>>>         (default_binds_local_p_1): Likewise.
>>>         (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>>>         via symtab_node.
>>>         (default_elf_asm_output_external): Emit visibility when specified.
>>
>> It looks like this patch broke alphaev68-linux-gnu [1]. There are many
>> failures of the type:
>>
>> /tmp/cck7V7MR.o: In function
>> `__static_initialization_and_destruction_0(int, int)':^M
>> (.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
>> `std::__cxx11::basic_string<char, std::char_traits<char>,
>> std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
>> .text section in
>> /space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
>> /space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
>> relocation against dynamic symbol
> 
> It could be related to:
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064
> 
> Before this bug fix, all common symbols don't bind locally,
> which is one of PR 32219 bugs.  After this fix, common
> symbols bind locally.  It may cause problems on targets with
> small data sections and common symbols aren't in small
> data section:

This is a destructor, and so obviously not a common symbol.

I'll have a look.


r~

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
  2015-02-16 13:25 [PATCH] PR rtl-optimization/32219: optimizer causees " Uros Bizjak
@ 2015-02-16 14:01 ` H.J. Lu
  2015-02-16 16:30   ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: H.J. Lu @ 2015-02-16 14:01 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: gcc-patches, Richard Henderson

On Mon, Feb 16, 2015 at 5:25 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> Hello!
>
>> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>>             Richard Henderson  <rth@redhat.com>
>>
>>         PR rtl/32219
>>         * cgraphunit.c (cgraph_node::finalize_function): Set definition
>>         before notice_global_symbol.
>>         (varpool_node::finalize_decl): Likewise.
>>         * varasm.c (default_binds_local_p_2): Rename from
>>         default_binds_local_p_1, add weak_dominate argument.  Use direct
>>         returns instead of assigning to local variable.  Unify varpool and
>>         cgraph paths via symtab_node.  Reject undef weak variables before
>>         testing visibility.  Reorder tests for simplicity.
>>         (default_binds_local_p): Use default_binds_local_p_2.
>>         (default_binds_local_p_1): Likewise.
>>         (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>>         via symtab_node.
>>         (default_elf_asm_output_external): Emit visibility when specified.
>
> It looks like this patch broke alphaev68-linux-gnu [1]. There are many
> failures of the type:
>
> /tmp/cck7V7MR.o: In function
> `__static_initialization_and_destruction_0(int, int)':^M
> (.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
> `std::__cxx11::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
> .text section in
> /space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
> /space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
> relocation against dynamic symbol

It could be related to:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65064

Before this bug fix, all common symbols don't bind locally,
which is one of PR 32219 bugs.  After this fix, common
symbols bind locally.  It may cause problems on targets with
small data sections and common symbols aren't in small
data section:

1. Since common symbols bind locally, backend may assume
they are in small data section and lead to link-time failure.
2. Backend assume common symbols are never in small
data section.  But a definition in small data section may
override a common symbol, which still binds lcoally, and
turn a reference to common symbol to reference to small
data section.  This also may lead to link-time failure.

Those targets can't assume common symbols are in
small data section since it may change at link-time.

The most conservative solution is to make common
symbol doesn't bind locally for targets which defines
TARGET_IN_SMALL_DATA_P.

-- 
H.J.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [PATCH] PR rtl-optimization/32219: optimizer causees wrong code in pic/hidden/weak symbol checking
@ 2015-02-16 13:25 Uros Bizjak
  2015-02-16 14:01 ` H.J. Lu
  0 siblings, 1 reply; 53+ messages in thread
From: Uros Bizjak @ 2015-02-16 13:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: H.J. Lu, Richard Henderson

Hello!

> 2015-02-12  H.J. Lu  <hongjiu.lu@intel.com>
>             Richard Henderson  <rth@redhat.com>
>
>         PR rtl/32219
>         * cgraphunit.c (cgraph_node::finalize_function): Set definition
>         before notice_global_symbol.
>         (varpool_node::finalize_decl): Likewise.
>         * varasm.c (default_binds_local_p_2): Rename from
>         default_binds_local_p_1, add weak_dominate argument.  Use direct
>         returns instead of assigning to local variable.  Unify varpool and
>         cgraph paths via symtab_node.  Reject undef weak variables before
>         testing visibility.  Reorder tests for simplicity.
>         (default_binds_local_p): Use default_binds_local_p_2.
>         (default_binds_local_p_1): Likewise.
>         (decl_binds_to_current_def_p): Unify varpool and cgraph paths
>         via symtab_node.
>         (default_elf_asm_output_external): Emit visibility when specified.

It looks like this patch broke alphaev68-linux-gnu [1]. There are many
failures of the type:

/tmp/cck7V7MR.o: In function
`__static_initialization_and_destruction_0(int, int)':^M
(.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
`std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
.text section in
/space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
/space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
relocation against dynamic symbol
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21^M
/space/homedirs/uros/local/bin/ld: final link failed: Nonrepresentable
section on output^M

An example is g++.dg/torture/pr60750.C :

/space/uros/gcc-build/gcc/testsuite/g++/../../xg++
-B/space/uros/gcc-build/gcc/testsuite/g++/../../
/space/homedirs/uros/gcc-svn/trunk/gcc/testsuite/g++.dg/torture/pr60750.C
-fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++
-I/space/homedirs/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/include/alphaev68-unknown-linux-gnu
-I/space/homedirs/uros/gcc-build/alphaev68-unknown-linux-gnu/libstdc++-v3/include
-I/space/homedirs/uros/gcc-svn/trunk/libstdc++-v3/libsupc++
-I/space/homedirs/uros/gcc-svn/trunk/libstdc++-v3/include/backward
-I/space/homedirs/uros/gcc-svn/trunk/libstdc++-v3/testsuite/util
-fmessage-length=0 -O0 -std=c++11
-L/space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs
-B/space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs
-L/space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs
-lm -o ./pr60750.exe^M
/space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
relocation against dynamic symbol
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21^M
/tmp/cck7V7MR.o: In function
`__static_initialization_and_destruction_0(int, int)':^M
(.text+0x3ac): relocation truncated to fit: GPRELHIGH against symbol
`std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >::~basic_string()@@GLIBCXX_3.4.21' defined in
.text section in
/space/uros/gcc-build/alphaev68-unknown-linux-gnu/./libstdc++-v3/src/.libs/libstdc++.so^M
/space/homedirs/uros/local/bin/ld: /tmp/cck7V7MR.o: gp-relative
relocation against dynamic symbol
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21^M
/space/homedirs/uros/local/bin/ld: final link failed: Nonrepresentable
section on output^M
collect2: error: ld returned 1 exit status^M
compiler exited with status 1

[1] https://gcc.gnu.org/ml/gcc-testresults/2015-02/msg01867.html

Uros.

^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2015-03-06 11:14 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-06 16:23 [PATCH] PR rtl-optimization/32219: optimizer causes wrong code in pic/hidden/weak symbol checking H.J. Lu
2015-02-06 21:31 ` Jack Howarth
2015-02-06 21:41   ` H.J. Lu
2015-02-06 21:51     ` Jack Howarth
2015-02-07  1:50       ` H.J. Lu
2015-02-07  1:51     ` Jack Howarth
2015-02-07  1:55       ` H.J. Lu
2015-02-07  2:25         ` Jack Howarth
2015-02-07  8:28         ` Jack Howarth
2015-02-07 12:27           ` H.J. Lu
2015-02-07 15:11             ` Jack Howarth
2015-02-07 15:25               ` Jack Howarth
2015-02-07 15:56               ` H.J. Lu
2015-02-07 16:45                 ` H.J. Lu
2015-02-08 18:24                   ` Jack Howarth
2015-02-09 17:26                     ` Mike Stump
2015-02-10 18:33                       ` Jack Howarth
2015-02-10 21:19                   ` Richard Henderson
2015-02-10 21:25                     ` H.J. Lu
2015-02-11 14:35                     ` Jack Howarth
2015-02-12  6:23                     ` [PATCH] PR rtl-optimization/32219: optimizer causees " Richard Henderson
2015-02-12 18:16                       ` H.J. Lu
2015-02-12 18:58                         ` H.J. Lu
2015-02-12 19:25                           ` Richard Henderson
2015-02-12 23:04                             ` H.J. Lu
2015-02-12 23:05                               ` H.J. Lu
2015-02-13  0:05                                 ` Richard Henderson
2015-02-13  4:14                                   ` H.J. Lu
2015-02-13  5:11                                     ` Richard Henderson
2015-02-18 14:17                                       ` Alex Velenko
2015-02-19 13:12                                         ` H.J. Lu
2015-02-19 15:02                                         ` Richard Henderson
2015-02-19 17:25                                           ` Alex Velenko
2015-02-19 17:27                                             ` Richard Henderson
2015-03-03 15:58                                               ` Alex Velenko
2015-03-05 14:55                                                 ` Alex Velenko
2015-03-05 15:31                                                   ` Ramana Radhakrishnan
2015-03-06 11:14                                                     ` Alex Velenko
2015-02-12 19:16                         ` Jack Howarth
2015-02-12 19:18                           ` H.J. Lu
2015-02-12 19:39                             ` Jack Howarth
2015-02-07 19:37                 ` [PATCH] PR rtl-optimization/32219: optimizer causes " Jack Howarth
2015-02-16 13:25 [PATCH] PR rtl-optimization/32219: optimizer causees " Uros Bizjak
2015-02-16 14:01 ` H.J. Lu
2015-02-16 16:30   ` Richard Henderson
2015-02-16 16:38     ` H.J. Lu
2015-02-19 21:07     ` Uros Bizjak
2015-02-19 21:08       ` H.J. Lu
2015-02-19 21:16         ` H.J. Lu
2015-02-19 21:16         ` Richard Henderson
2015-02-19 21:35       ` Richard Henderson
2015-02-19 21:43         ` H.J. Lu
2015-02-19 23:39           ` Uros Bizjak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).