Bug 51117 - [4.7 regression] rev.181172 causes glibc build failure
Summary: [4.7 regression] rev.181172 causes glibc build failure
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.7.0
: P1 normal
Target Milestone: 4.7.0
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-13 11:31 UTC by Markus Trippelsdorf
Modified: 2011-12-15 17:27 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-11-29 00:00:00


Attachments
gcc47-pr51117.patch (878 bytes, patch)
2011-12-08 17:24 UTC, Jakub Jelinek
Details | Diff
gcc47-pr51117-sink.patch (2.36 KB, patch)
2011-12-09 16:09 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Trippelsdorf 2011-11-13 11:31:19 UTC
On x86_64-pc-linux-gnu I get the following error when I build the latest
git version of glibc:

cc   -nostdlib -nostartfiles -r -o /var/tmp/glibc-build/libc_pic.os \
 -Wl,-d -Wl,--whole-archive /var/tmp/glibc-build/libc_pic.a -o /var/tmp/glibc-build/libc_pic.os
gcc   -nostdlib -nostartfiles -r -o /var/tmp/glibc-build/elf/librtld.map.o '-Wl,-(' /var/tmp/glibc-build/elf/dl-allobjs.os /var/tmp/glibc-build/libc_
pic.a -lgcc '-Wl,-)' -Wl,-Map,/var/tmp/glibc-build/elf/librtld.mapT
/var/tmp/glibc-build/libc_pic.a(dl-addr.os): In function `_dl_addr_inside_object':
/var/tmp/glibc/elf/dl-addr.c:155: multiple definition of `_dl_addr_inside_object'
/var/tmp/glibc-build/elf/dl-allobjs.os:/var/tmp/glibc/elf/dl-open.c:673: first defined here
/var/tmp/glibc-build/libc_pic.a(init-first.os):(.data+0x0): multiple definition of `__libc_multiple_libcs'
/var/tmp/glibc-build/elf/dl-allobjs.os:/var/tmp/glibc/elf/rtld.c:658: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [/var/tmp/glibc-build/elf/librtld.map] Error 1
make[2]: *** Waiting for unfinished jobs....

I've git bisected this failure to:

3c25489e88a7ea2937c19abff9163d9f7d8ca53a is the first bad commit
commit 3c25489e88a7ea2937c19abff9163d9f7d8ca53a
Author: matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue Nov 8 16:47:16 2011 +0000

        * gengtype.c (write_field_root): Avoid out-of-scope access of newv.
    
        * tree-stdarg.c (execute_optimize_stdarg): Accept clobbers.
    
        * tree.h (TREE_CLOBBER_P): New macro.
        * gimple.h (gimple_clobber_p): New inline function.
        * gimplify.c (gimplify_bind_expr): Add clobbers for all variables
        that go out of scope and live in memory.
        * tree-ssa-operands.c (get_expr_operands): Transfer volatility also
        for constructors.
        * cfgexpand.c (decl_to_stack_part): New static variable.
        (add_stack_var): Allocate it, and remember mapping.
        (fini_vars_expansion): Deallocate it.
        (stack_var_conflict_p): Add early outs.
        (visit_op, visit_conflict, add_scope_conflicts_1,
        add_scope_conflicts): New static functions.
        (expand_used_vars_for_block): Don't call add_stack_var_conflict, tidy.
        (expand_used_vars): Add scope conflicts.
        (expand_gimple_stmt_1): Expand clobbers to nothing.
        (expand_debug_expr): Ditto.
    
        * tree-pretty-print.c (dump_generic_node): Dump clobbers nicely.
        * tree-ssa-live.c (remove_unused_locals): Remove clobbers that
        refer to otherwise unused locals.
        * tree-sra.c (build_accesses_from_assign): Ignore clobbers.
        * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Clobbers of
        SSA names aren't necessary.
        (propagate_necessity): Accept and ignore constructors on the rhs,
        tidy.
        * gimple.c (walk_gimple_op): Accept constructors like mem_rhs.
        * tree-ssa-structalias.c (find_func_aliases): Clobbers don't store
        any known value.
        * tree-ssa-sccvn.c (vn_reference_lookup_3): Ditto, in particular they
        don't zero-initialize something.
        * tree-ssa-phiopt.c (cond_if_else_store_replacement_1): Ignore
        clobber RHS, we don't want PHI nodes with those.
    
    testsuite/
        * gcc.dg/tree-ssa/20031015-1.c: Adjust.
        * g++.dg/tree-ssa/ehcleanup-1.C: Ditto.
        * g++.dg/eh/builtin1.C: Rewrite to not use local variables.
        * g++.dg/eh/builtin2.C: Ditto.
        * g++.dg/eh/builtin3.C: Ditto.
    
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181172 138bc75d-0d04-0410-961f-82ee72b054a4
Comment 1 Igor Zamyatin 2011-11-15 10:32:30 UTC
I see the same problem. Anybody else met this issue?
Comment 2 Michael Matz 2011-11-15 15:50:21 UTC
See http://sourceware.org/bugzilla/show_bug.cgi?id=13411 for analysis and 
possible patch.  The newly emitted calls to _Unwind_Resume suck in new object
files that weren't included before leading to these multiple defined symbols.
glibc needs to deal with this in one or the other way.
Comment 3 Richard Henderson 2011-11-29 18:06:55 UTC
I think this is a gcc bug.  In particular, one of two things ought to happen:

(1) Use the form of try_finally that ignores EH.  This would lose clobber
    information on EH paths; dunno if this really turns out to be important.

(2) Remove EH cleanup handlers that only involve clobbers which lead to 
    function exit via REX.  This would wait until pass_lower_eh_dispatch,
    as that's the first point at which we know whether we actually exit
    the function, post-inlining.
Comment 4 Jakub Jelinek 2011-12-05 14:57:39 UTC
I agree it is a gcc bug, please see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51275
for more information.
Comment 5 Jakub Jelinek 2011-12-08 17:24:27 UTC
Created attachment 26025 [details]
gcc47-pr51117.patch

Untested fix.  This improves e.g.:
struct A { char buf[64]; };

void bar (A *);

void
foo ()
{
  {
    A a;
    bar (&a);
    if (a.buf[13])
      throw 1;
  }
  {
    A b;
    bar (&b);
    if (b.buf[13])
      throw 2;
  }
}

back to 4.6 generated code quality, but it doesn't already e.g.:
struct A
{
  char buf[64];
};
void bar (A *);
void
foo ()
{
  A c;
  bar (&c);
  try
  {
    {
      A a;
      bar (&a);
      if (a.buf[13])
throw 1;
      else if (a.buf[52])
throw 3;
    }
    {
      A b;
      bar (&b);
      if (b.buf[13])
throw 2;
    }
  }
  catch ( ...)
  {
    throw;
  }
}

I think it should be safe to move the clobbers to the EH destination of the !stmt_can_throw_external (stmt) GIMPLE_RESX for that, but am not 100% sure about that yet and would prefer to do it incrementally anyway.
Comment 6 Jakub Jelinek 2011-12-09 11:48:33 UTC
Author: jakub
Date: Fri Dec  9 11:48:30 2011
New Revision: 182158

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182158
Log:
	PR tree-optimization/51117
	* tree-eh.c (optimize_clobbers): New function.
	(execute_lower_eh_dispatch): Call it.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-eh.c
Comment 7 Jakub Jelinek 2011-12-09 16:09:48 UTC
Created attachment 26034 [details]
gcc47-pr51117-sink.patch

So far untested attempt to sink clobbers if a BB with all EH pred edges and a single EH succ edge, ending with internal throwing RESX contains other than that just CLOBBER stmts (and optionally debug stmts).
Such BBs force us to immediately rethrow with no actual code in between, when the clobber stmts are sunk into the successor, we can actually ehcleanup those.
Had to tweak a little bit the conflict detection in the expander for that though, without that it would think the vars still conflict on the incoming edge (even when no actual insns that might touch memory appear before the clobber).
Comment 8 Jakub Jelinek 2011-12-09 20:50:50 UTC
Author: jakub
Date: Fri Dec  9 20:50:40 2011
New Revision: 182177

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182177
Log:
	PR tree-optimization/51117
	* tree-eh.c (optimize_clobbers): Don't remove just one
	clobber, but all consecutive clobbers before RESX.
	Use gimple_clobber_p predicate.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-eh.c
Comment 9 Michael Matz 2011-12-13 13:59:42 UTC
Author: matz
Date: Tue Dec 13 13:59:35 2011
New Revision: 182283

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182283
Log:
	PR tree-optimization/51117
	* tree-eh.c (sink_clobbers): New function.
	(execute_lower_eh_dispatch): Call it for BBs ending with
	internally throwing RESX.
	* cfgexpand.c (add_scope_conflicts_1): Add all conflicts only
	at the first real instruction.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cfgexpand.c
    trunk/gcc/tree-eh.c
Comment 10 Jakub Jelinek 2011-12-13 14:04:52 UTC
Fixed.
Comment 11 Jakub Jelinek 2011-12-15 17:27:11 UTC
Author: jakub
Date: Thu Dec 15 17:27:08 2011
New Revision: 182379

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182379
Log:
	PR tree-optimization/51117
	* g++.dg/opt/pr51117.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/opt/pr51117.C
Modified:
    trunk/gcc/testsuite/ChangeLog