[Bug c++/83908] New: -fvisibility=hidden not setting the visibility of the resolver/ifunc created for attribute target

2018-01-16 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83908

Bug ID: 83908
   Summary: -fvisibility=hidden not setting the visibility of the
resolver/ifunc created for attribute target
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
  Target Milestone: ---

Given the c++ code

int __attribute__((target("sse4.2"))) foo_overload(int);
int __attribute__((target("default"))) foo_overload(int);

int bar() {
  return  foo_overload(1);
}

gcc produces

10: 32 FUNCWEAK   DEFAULT6
_Z12foo_overloadi.resolver
11:  0 NOTYPE  GLOBAL DEFAULT  UND __cpu_indicator_init
12:  0 NOTYPE  GLOBAL DEFAULT  UND __cpu_model
13:  0 NOTYPE  GLOBAL DEFAULT  UND
_Z12foo_overloadi.sse4.2
14:  0 NOTYPE  GLOBAL DEFAULT  UND _Z12foo_overloadi
15: 32 IFUNC   GLOBAL DEFAULT6
_Z23_Z12foo_overloadi.ifunci
16: 10 FUNCGLOBAL HIDDEN 2 _Z3barv

Note how only _Z3barv is hidden.

[Bug c/83782] New: Inconsistent address for hidden ifunc in a shared library

2018-01-10 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83782

Bug ID: 83782
   Summary: Inconsistent address for hidden ifunc in a shared
library
   Product: gcc
   Version: 7.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
  Target Milestone: ---

Created attachment 43092
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43092=edit
testcase

If a function with hidden visibility is implemented with an ifunc, different
translation units have different opinions as to what its address is.

The translation unit implementing the function gets its address with

movqfoo@GOTPCREL(%rip), %rax

That is, it finds the address of the actual function after it is selected.

Any translation unit will use

leaqfoo(%rip), %rax

which the linker translates to the address of the plt.

The net result is that the attached program finds two addresses for the same
function:

$ ./t
0x7fc5f331360a 0x7fc5f3313510

Gives the desire to allow ifuncs to be used by changing just the implementation
(not the declaration), I think the only solution is to use the plt address in
both translation units.

[Bug c++/82906] thread_local address not uniqued across shared libraries

2017-11-08 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82906

--- Comment #2 from Rafael Avila de Espindola  ---
(In reply to Andrew Pinski from comment #1)
> Could this be a bug in ld.so rather than gcc?  Not doing copy relocs for TLS?

I don't think there is enough information left for ld.so to fix the situation.

With local dynamic the relocations in test.so are

Relocation section '.rela.dyn' at offset 0x2a8 contains 1 entries:
  Offset  Info   Type   Sym. ValueSym. Name +
Addend
00200ff0  0010 R_X86_64_DTPMOD640

Relocation section '.rela.plt' at offset 0x2c0 contains 1 entries:
  Offset  Info   Type   Sym. ValueSym. Name +
Addend
00201018  00010007 R_X86_64_JUMP_SLO  __tls_get_addr +
0

So it will always get variable in test.so.

[Bug c++/82906] New: thread_local address not uniqued across shared libraries

2017-11-08 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82906

Bug ID: 82906
   Summary: thread_local address not uniqued across shared
libraries
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
  Target Milestone: ---

Given

test.h:
inline int *foo() {   
  static thread_local int i = 42; 
  return   
}   

test.cpp:
#include "test.h" 
int *bar() { return foo(); } 

test2.cpp:
#include "test.h"
#include 
int *bar();
int main() {
  printf("%d\n", bar() == foo());
  return 0;
}

If test.cpp is compiled with "gcc -c -O2 -fPIC test.c", the resulting .o has a
R_X86_64_TLSLD R_X86_64_DTPOFF32 pair.

Compiling the rest of the program with

g++ test.o -shared -o test.so"
g++ test2.cpp test.so -o t  -Wl,-rpath="\$ORIGIN"

produces an executable that prints 0 when run. It should print 1, that is,
bar() and foo() should find the same address.

Changing test.o to use general dynamic instead of local dynamic solves the
problem.

[Bug debug/82630] Bogus DW_AT_GNU_call_site_value

2017-10-20 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630

--- Comment #6 from Rafael Avila de Espindola  ---
(In reply to H.J. Lu from comment #3)
> (In reply to Jakub Jelinek from comment #2)
> > The problem is the assembler's special treatment of _GLOBAL_OFFSET_TABLE_,
> > that
> > .long _GLOBAL_OFFSET_TABLE_ or .quad _GLOBAL_OFFSET_TABLE_ on x86 doesn't
> > actually assemble as normal relocation against that symbol, but as a special
> > relocation.
> 
> Should I change assembler to generate R_386_32 for
> 
> .long _GLOBAL_OFFSET_TABLE_

I would love for the _GLOBAL_OFFSET_TABLE_ special case to go away, but for
doing that gcc would first have to change from printing

call__x86.get_pc_thunk.bx
addl$_GLOBAL_OFFSET_TABLE_, %ebx

to printing

call__x86.get_pc_thunk.bx
addl$_GLOBAL_OFFSET_TABLE_ - ., %ebx

which already produces the exactly same binary with gas.

[Bug debug/82630] New: Bogus DW_AT_GNU_call_site_value

2017-10-19 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630

Bug ID: 82630
   Summary: Bogus DW_AT_GNU_call_site_value
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
  Target Milestone: ---

Created attachment 42407
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42407=edit
testcase

If the attached file is compiled with "g++ test.cpp -fPIC  -g  -O3 -m32", the
produced dwarf has

DW_AT_location  len 0x0001: 52: DW_OP_reg2

Which means an argument is begin passed in edx. It also has

DW_AT_GNU_call_site_value   len 0x000e: 7300031c0322:
DW_OP_breg3+0 DW_OP_addr 0x DW_OP_minus DW_OP_addr 0x
DW_OP_plus

The first DW_op_addr is

 .long   _GLOBAL_OFFSET_TABLE_

and the second one is

.long   .LC0

The first line actually produces a R_386_GOTPC, so it looks like the expression
is computing

(ebx - (GOTEND - PC)) + LC0

The code using LC0 is

_Z3fn3Pi:
pushl   %esi
pushl   %ebx
xorl%ebx, %ebx
call__x86.get_pc_thunk.si
addl$_GLOBAL_OFFSET_TABLE_, %esi
subl$12, %esp
movl24(%esp), %eax
leal.LC0@GOTOFF(%esi), %edx
pushl   %ebx
movl%esi, %ebx
pushl   %eax
call_ZL3fn2PiPKc1C.constprop.0

So at the point of the call ebx is GOTEND. This suggests that gcc is actually
trying to compute

(ebx - GOTEND) + LC0 but getting R_386_GOTPC wrong. But the expression also
simplifies to just LC0, which is what is actually in edx.

[Bug debug/82631] New: Bogus DW_AT_GNU_call_site_value

2017-10-19 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82631

Bug ID: 82631
   Summary: Bogus DW_AT_GNU_call_site_value
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
  Target Milestone: ---

Created attachment 42408
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42408=edit
testcase

If the attached file is compiled with "g++ test.cpp -fPIC  -g  -O3 -m32", the
produced dwarf has

DW_AT_location  len 0x0001: 52: DW_OP_reg2

Which means an argument is begin passed in edx. It also has

DW_AT_GNU_call_site_value   len 0x000e: 7300031c0322:
DW_OP_breg3+0 DW_OP_addr 0x DW_OP_minus DW_OP_addr 0x
DW_OP_plus

The first DW_op_addr is

 .long   _GLOBAL_OFFSET_TABLE_

and the second one is

.long   .LC0

The first line actually produces a R_386_GOTPC, so it looks like the expression
is computing

(ebx - (GOTEND - PC)) + LC0

The code using LC0 is

_Z3fn3Pi:
pushl   %esi
pushl   %ebx
xorl%ebx, %ebx
call__x86.get_pc_thunk.si
addl$_GLOBAL_OFFSET_TABLE_, %esi
subl$12, %esp
movl24(%esp), %eax
leal.LC0@GOTOFF(%esi), %edx
pushl   %ebx
movl%esi, %ebx
pushl   %eax
call_ZL3fn2PiPKc1C.constprop.0

So at the point of the call ebx is GOTEND. This suggests that gcc is actually
trying to compute

(ebx - GOTEND) + LC0 but getting R_386_GOTPC wrong. But the expression also
simplifies to just LC0, which is what is actually in edx.

[Bug middle-end/54303] -fdata-sections -ffunction-sections and -fmerge-constants do not work well together

2015-02-03 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54303

Rafael Avila de Espindola rafael.espindola at gmail dot com changed:

   What|Removed |Added

 CC||rafael.espindola at gmail dot 
com

--- Comment #13 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
See also
https://sourceware.org/bugzilla/show_bug.cgi?id=17902


[Bug c++/50986] weak static data members with constant initializers emitted in .rodata, leading to segfault on startup

2014-10-23 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50986

--- Comment #3 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
In clang this was fixed by putting a .init_array section in the same comdat as
the variable it is initializing. That way if the variable is dropped, so is the
initialization code.


[Bug c++/62306] [4.9/5 Regression?] Change in the comdat used for constructors

2014-09-04 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62306

--- Comment #10 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
(In reply to Jakub Jelinek from comment #9)
 (In reply to Jason Merrill from comment #8)
  I think I'm sympathetic to Rafael's argument that we should stick with the
  4.7 behavior since that's what most deployed GCCs currently do.
 
 4.5+4.6+4.9 is more released compilers than 4.7/4.8 though, and 4.9 is
 already widely deployed too, IMHO it is worse to change this again
 mid-release.

Another option to start using a D6 COMDAT that is defined to always contain D1
and D2 and never contain D0.

This would mean a small bloat when mixing some .o files compiled with 5 and
some with previous releases, but would also mean better codegen and a clean
state for 5 and newer.


[Bug c++/62306] [4.9/5 Regression?] Change in the comdat used for constructors

2014-09-02 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62306

--- Comment #4 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
So it looks like the reason was

jason My thinking was that the ABI change should also support implementations
that implement D0 as another entry point into the destructor

jakub jason: leaving D0 out of D5 would be easiest, but would perhaps be a
problem for other implementations
-

But I am not sure what the extra entry point would look like. D0 has a call to
delete *after* the call to the other destructor, so there is no tail that could
be used as an alternative entry point.


[Bug c++/62306] [4.9/5 Regression?] Change in the comdat used for constructors

2014-09-02 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62306

--- Comment #6 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
OK, so should we declare r206182 an unintentional bug fix and mark this bug
wontfix?

To be clear, the ABI then is

For any class an implementation has the option of using one comdat per
constructor/destructor or using a C5/D5 comdat. I may make that decision based
on any profitability criterion. If using a C5/D5 comdat the rules are

* A C5 comdat must have C1 and C2.
* If a class has a virtual destructor, the D5 comdat must have D0, D1 and D2
* If a class has a non-virtual destructor, the D5 comdat must have only the D1
and D2 destructors. That is true even if the implementation uses D0 instead of
a call to D1 + _ZdlPv to implement delete *x

Should this be documented in

https://refspecs.linuxbase.org/cxxabi-1.86.html ?


[Bug c++/62306] [4.9/5 Regression?] Change in the comdat used for constructors

2014-09-02 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62306

--- Comment #7 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
(In reply to Rafael Avila de Espindola from comment #6)
 OK, so should we declare r206182 an unintentional bug fix and mark this
 bug wontfix?
 

One thing to keep in mind. If r206182 was the bug fix, r176071 was the revision
that introduced the bug. That was when trunk was 4.7.0.

A quick test with the current branches shows that for the example in the bug
description

4.6: Puts D0 in D5
4.7: Puts D0 in D0
4.8: Puts D0 in D0
4.9: Puts D0 in D5
trunk: Puts D0 in D5

in the case of the 4.9 branch, 

Given that most linux distros are still with 4.8, the safest thing to do might
be to say that 4.7 changed the ABI and patch 4.9 and trunk to put D0 in its own
comdat.


[Bug c++/62306] [4.9/5 Regression?] Change in the comdat used for constructors

2014-09-01 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62306

--- Comment #2 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
This is again visible on trunk now that pr62302 has been fixed (thanks!).

It doesn't seem profitable to ever put D0 in the D5 comdat. It cannot be equal
to D1 or D2, so putting it there just constrains the linker unnecessarily.


[Bug c++/62306] New: [4.9/5 Regression?] Change in the comdat used for constructors

2014-08-29 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62306

Bug ID: 62306
   Summary: [4.9/5 Regression?] Change in the comdat used for
constructors
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
CC: jason at redhat dot com

Given

struct Option {
  virtual ~Option() {}
};
template class DataType class opt : public Option {};
template class optint;

before r206182 

gcc would print

.section.text._ZN3optIiED0Ev,axG,@progbits,_ZN3optIiED0Ev,comdat

now it prints

.section.text._ZN3optIiED0Ev,axG,@progbits,_ZN3optIiED5Ev,comdat

It looks reasonable to use D5, but it is not clear if that was intentional and
there are no tests for this change in behaviour.


[Bug c++/62302] New: Change in the comdat used for constructors

2014-08-28 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62302

Bug ID: 62302
   Summary: Change in the comdat used for constructors
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
CC: hubicka at gcc dot gnu.org

It looks like an unintended consequence of r211434 wast that given

template typename T struct foo { foo(); };
template typename T fooT::foo() {}
template class fooint;

gcc now prints

.section.text._ZN3fooIiEC2Ev,axG,@progbits,_ZN3fooIiEC2Ev,comdat

before it did

.section.text._ZN3fooIiEC2Ev,axG,@progbits,_ZN3fooIiEC5Ev,comdat

Note the change in comdat.


[Bug lto/53808] Undefined symbol when building a library with lto

2014-07-22 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53808

--- Comment #12 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
Note that this bug is present once more when -fno-use-all-virtuals is used.
With the original testcase gcc again produces an undefined reference to
_ZN3barD0Ev.

Is -fno-use-all-virtuals intended to be an abi breaking option? If so it would
be nice to document that.


[Bug ipa/61659] [4.9/4.10 Regression] Extra undefined symbol because of devirtualization

2014-07-01 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61659

--- Comment #15 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
(In reply to Jason Merrill from comment #14)
 Right.  My patch causes us to synthesize ~I so that it's available for
 devirtualization, which we weren't doing before.  This is allowed by the C++
 standard: 3.2p3 says A virtual member function is odr-used if it is not
 pure. so the compiler is free to instantiate/synthesize any virtual
 function.
 
 Avoiding this while still getting the devirtualization benefit would require
 some mechanism for devirtualization to call back into the front end to
 trigger the instantiation/synthesis directly.  This might be workable for an
 individual translation unit, but not for LTO.

And make which c++ errors user see dependent on which optimizations they run,
which is not very friendly. I agree your approach is better.

Markus Trippelsdorf:

The include should go where it is used, so in GCMetadata.h.


[Bug c++/61659] New: Extra undefined symbol because of devirtualization

2014-06-30 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61659

Bug ID: 61659
   Summary: Extra undefined symbol because of devirtualization
   Product: gcc
   Version: 4.10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
CC: hubicka at gcc dot gnu.org

Given

struct generic_parser_base {
  virtual void getOption();
  void getExtraOptionNames() { getOption(); }
};
template class DataType struct parser : public generic_parser_base {
  virtual void getOption() {}
};
struct PassNameParser : public parserint {
  PassNameParser();
};
struct list {
  PassNameParser Parser;
  virtual void getExtraOptionNames() { return Parser.getExtraOptionNames(); }
};
list PassList;

gcc 4.9 and trunk will produce an undefined reference to
_ZN6parserIiE9getOptionEv (parserint::getOption()) which suggest that the
template is not being instantiated when the call is devirtualized.

Using -fno-devirtualize avoids the bug.


[Bug c++/61659] Extra undefined symbol because of devirtualization

2014-06-30 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61659

--- Comment #1 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
The undefined is still present with -fno-devirtualize-speculatively.


[Bug ipa/61555] [4.9/4.10 Regression] LLVM build failure

2014-06-30 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61555

Rafael Avila de Espindola rafael.espindola at gmail dot com changed:

   What|Removed |Added

 CC||rafael.espindola at gmail dot 
com

--- Comment #4 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
A valid testcase reduction is at
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61659


[Bug ipa/61659] [4.9/4.10 Regression] Extra undefined symbol because of devirtualization

2014-06-30 Thread rafael.espindola at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61659

--- Comment #4 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
I ran the testcase with just -O2 (original code with -O3, but the reduced
testcase with -O2).

getOption will be part of the vtable, but it can end up being hidden.

In the original source code it ends up being hidden because of
-fvisibility-inlines-hidden (I think, haven't checked).

It also seems invalid to produce the extra undefined at a more fundamental
level. The ABI doesn't say that symbol has to be exposed. In particular, the
vtable can be in another DSO and it is legal to remeve the symbol of getOption
from the dso since the compiler knows that any user can emit a copy.

The above optimization is why PREVAILING_DEF_IRONLY_EXP was added to the gold
plugin api and both gcc and llvm LTO's optimizations do it.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53808 for a related
discussion.


[Bug c/60490] New: please define __LITTLE_ENDIAN__/__BIG_ENDIAN__ for every target where it makes sense

2014-03-10 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60490

Bug ID: 60490
   Summary: please define __LITTLE_ENDIAN__/__BIG_ENDIAN__ for
every target where it makes sense
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
CC: chandlerc at gmail dot com, echristo at gmail dot com

We noticed that both clang and gcc were fairly inconsistent and incompatible as
to which targets cause __LITTLE_ENDIAN__/__BIG_ENDIAN__ to be defined.

They are not as flexible __BYTE_ORDER__ (cannot represent
__ORDER_PDP_ENDIAN__), but they cover the needs of most software. On the clang
side we decided to just always define them if the target is little endian or
big endian.

It would be nice if gcc could do the same.


[Bug ipa/59469] [4.8/4.9 Regression] LLVM build failure with gcc LTO

2014-01-09 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59469

Rafael Avila de Espindola rafael.espindola at gmail dot com changed:

   What|Removed |Added

 CC||rafael.espindola at gmail dot 
com

--- Comment #24 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
(In reply to Jan Hubicka from comment #22)
 00010 // This file implements the stickier parts of the
 SymbolTableListTraits class,
 00011 // and is explicitly instantiated where needed to avoid defining all
 this code
 00012 // in a widely used header.
 
 I would thus say that libLLVMAsmParser.s misses the explicit instantiation
 in it?

It looks like the expected/correct result is for libLLVMAsmParser.so to have an
undefined reference that is satisfied by a definition in libLLVMCore.so. The
definition should come from an explicit template instantiation in Function.cpp.

Markus, do you see the definition in Function.o? What about libLLVMCore.so?


[Bug ipa/59469] [4.8/4.9 Regression] LLVM build failure with gcc LTO

2014-01-09 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59469

--- Comment #26 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
 Yes, is see the weak symbol both in BasicBlock.o and Function.o.
 However it gets optimized away when I link them with -flto -O3 into
 libLLVMCore.so (see comment 0).

That optimization seems invalid. There is a explicit template instantiation
definition, so it is valid for other dsos to have an undefined reference.

 Honza says it is an error to have the symbol undefined in
 libLLVMAsmParser.so.
 (The undefined symbol comes from LLParser.cpp)


[Bug c++/59300] visibility computation misses some attributes in namespaces

2013-12-07 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59300

--- Comment #1 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
clang had an even stranger behavior
(http://llvm.org/bugs/show_bug.cgi?id=18174). I fixed that in a way that it now
agrees with gcc on the testcase in this bug.

It would still be nice to know if the current behavior is intentional or not.


[Bug c++/59300] New: visibility computation misses some attributes in namespaces

2013-11-26 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59300

Bug ID: 59300
   Summary: visibility computation misses some attributes in
namespaces
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com

Given

namespace nfoo {
  class foo {
void f();
  };
}
namespace nfoo __attribute__((visibility(hidden))) {
  void foo::f() {}
}

gcc trunk r205392 produces a symbol with default visibility. GCC normally
considers the visibility of followup decls, so I was expecting hidden.


[Bug c++/59236] Mixing -O0 and -O2 object causes link error because of corrupted comadts

2013-11-21 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59236

--- Comment #2 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
(In reply to H.J. Lu from comment #1)
 Works on Linux/x86-64.

Yes, it is a COFF only issue (tested on mingw).


[Bug c++/59236] New: Mixing -O0 and -O2 object causes link error because of corrupted comadts

2013-11-21 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59236

Bug ID: 59236
   Summary: Mixing -O0 and -O2 object causes link error because of
corrupted comadts
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
Target: mingw

$ cat test1.cpp
#include test.h
struct zed : public foo {
  virtual ~zed();
};
zed::~zed() {}

$ cat test2.cpp
#include test.h
struct zed2 : public foo {
  virtual ~zed2();
};
zed2::~zed2() {}

$ cat test.h
class foo {
  virtual void bar() { __builtin_unreachable(); }
};

$ i686-w64-mingw32-g++ -fno-rtti -fno-exceptions -c test1.cpp
$ i686-w64-mingw32-g++ -fno-rtti -fno-exceptions -c test2.cpp -O2
$ i686-w64-mingw32-g++ -fno-rtti -fno-exceptions test1.o test2.o -o t.so
-shared

test2.o:test2.cpp:(.text$_ZN3foo3barEv+0x0): multiple definition of
`foo::bar()'
test1.o:test1.cpp:(.text$_ZN3foo3barEv[__ZN3foo3barEv]+0x0): first defined here
collect2: error: ld returned 1 exit status


The problem seems to be that test1.o has

  3 .text$_ZN3foo3barEv 000c      014c  2**2
  CONTENTS, ALLOC, LOAD, READONLY, CODE, LINK_ONCE_DISCARD
(COMDAT __ZN3foo3barEv 4)

while test2.o has

  4 .text$_ZN3foo3barEv         2**4
  ALLOC, LOAD, READONLY, CODE, LINK_ONCE_DISCARD

noticed that the comdat symbol is missing.


[Bug lto/53808] Undefined symbol when building a library with lto

2013-09-04 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53808

--- Comment #4 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com ---
The equivalent clang bug (llvm.org/pr13124) just got fixed by avoiding the
devirtualization in this case.

Not sure how similar the issues are internally, but I summarized what I found
in clang in:

http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130902/087810.html


[Bug c++/58045] New: gcc 4.8 produces an undefined reference to an inline function

2013-08-01 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58045

Bug ID: 58045
   Summary: gcc 4.8 produces an undefined reference to an inline
function
   Product: gcc
   Version: 4.8.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rafael.espindola at gmail dot com
CC: hubicka at gcc dot gnu.org, jason at redhat dot com

Created attachment 30582
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30582action=edit
testcase

This may or may not be a duplicate of bug 53808.

When compiling this testcase with

cc1plus llvm-ar.ii -quiet -std=c++11 -fprofile-arcs -o test.s -O2

The produced assembly has an undefined reference to
_ZNK4llvm14raw_fd_ostream11current_posEv, but this function is defined inline:

virtual uint64_t current_pos() const {
return pos;
}

This causes the link to fail when building with -fvisibility-inlines-hidden and
shared libraries.

GCC should avoid devirtualizing or emit a copy of the callee.


[Bug lto/53808] Undefined symbol when building a library with lto

2012-11-06 Thread rafael.espindola at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53808



--- Comment #1 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2012-11-06 13:53:00 UTC ---

I can see two options for fixing this



1) producing a copy of the destructor when we devirtualize and not

devirtualizing if we cannot emit one.

2) making the destructor that is emitted with the vtable strong.



On the clang side John McCall likes the first option better

(http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-June/022606.html). Jason, what

do you think?


[Bug c++/55170] New: incorrect mangling, should not include prefix

2012-11-01 Thread rafael.espindola at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55170



 Bug #: 55170

   Summary: incorrect mangling, should not include prefix

Classification: Unclassified

   Product: gcc

   Version: unknown

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: rafael.espind...@gmail.com





Given the testcase



namespace mozilla {

  templatetypename From

  struct IsConvertible {

static const bool value =true;

  };



  templatebool B

  struct EnableIf {

typedef int Type;

  };



  template typename S

  void Handle(S x, typename EnableIfIsConvertibleS::value::Type dummy) {

  }



  template void

  Handle(int x, EnableIfIsConvertibleint::value::Type dummy);

}



With current gcc trunk (193066) we get

$ gcc -fabi-version=0 -c test.cpp -w

$ nm test.o

 W

_ZN7mozilla6HandleIiEEvT_NS_8EnableIfIXsrNS_13IsConvertibleIS1_EE5valueEE4TypeE



And with clang



$ ./build/bin/clang -c test.cpp

$ nm test.o

 W

_ZN7mozilla6HandleIiEEvT_NS_8EnableIfIXsr13IsConvertibleIS1_EE5valueEE4TypeE



I initially thought the bug was in clang and reported llvm.org/pr14118, but

John McCall says that On cxx-abi-dev, I believe we decided that

prefixes on unresolved-names should be mangled essentially as written.


[Bug c++/55170] incorrect mangling, should not include prefix

2012-11-01 Thread rafael.espindola at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55170



--- Comment #1 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2012-11-01 20:29:02 UTC ---

The relevant thread seems to be



http://sourcerytools.com/pipermail/cxx-abi-dev/2011-April/002404.html


[Bug c++/54399] New: Invalid partial change from dynamic to static initialization

2012-08-28 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54399

 Bug #: 54399
   Summary: Invalid partial change from dynamic to static
initialization
Classification: Unclassified
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: rafael.espind...@gmail.com


I initially thought that this was a missed optimization in llvm
(http://llvm.org/pr13677), but Richard Smith convinced me this actually a bug
in gcc.

$ cat test1.cpp
struct foo {
  int a;
  int b;
  int c;
  int d;
  int e;
};
int zed();
int x = zed();
foo bar = {x, 1, 2, 3, 4};
$ cat test2.cpp
#include stdio.h
struct foo {
  int a;
  int b;
  int c;
  int d;
  int e;
};
extern foo bar;
int zed() { return bar.d; }
int main(void) {
  printf(%d\n, bar.a);
  return 0;
}

With gcc:

$ ~/gcc/build/gcc/xgcc -std=c++11 -B ~/gcc/build/gcc -c test1.cpp 
$ ~/gcc/build/gcc/xgcc -std=c++11 -B ~/gcc/build/gcc -c test2.cpp 
$ g++ test1.o test2.o -o t
$ ./t
3

and with clang:

$ clang test1.cpp test2.cpp -o t
[espindola@desktop llvm]$ ./t
0

If I understand Richard's argument correctly, the program must print 0 because

* from [basic.start.init] p2 both x and bar get dynamic initializations. In
that case x is initialized first and zed will see bar zero initialized.
* from p3, we can convert a variable to static initialization, but not part of
it. The possibilities are:
  1) Only x is converted to static initialization. x should be static
initialized to 0. When bar is dynamic initialized it will be initialized to {0,
1, 2, 3, 4}.
  2) Only bar is converted to static initialization. It should still be
initialized to {0, 1, 2, 3, 4}. In this case x is dynamically initialized to 3.
  3) Both x and bar are converted to static initialization. In this case x is 0
and bar is {0, 1, 2, 3, 4}.

The output produced by gcc doesn't match any of the possibilities provided by
the standard.


[Bug lto/53808] New: Undefined symbol when building a library with lto

2012-06-29 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53808

 Bug #: 53808
   Summary: Undefined symbol when building a library with lto
Classification: Unclassified
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: lto
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: rafael.espind...@gmail.com


The gcc lto plugin can drop a symbol that another translation unit has an
undefined reference to.

This might also be a bug in gcc (= 4.6, with and without lto) producing an
undefined reference, the ABI is not very clear.

$ cat test.h
struct foo {
 virtual ~foo();
};
struct bar : public foo {
 virtual void zed();
};
$ cat def.cpp
#include test.h
void bar::zed() {
}
$ cat undef.cpp
#include test.h
void f() {
 foo *x(new bar);
 delete x;
}

Compile with:

$ ~/gcc/build/gcc/xgcc -B ~/gcc/build/gcc/ -c undef.cpp -o undef.o -O3 -fPIC
$ nm undef.o | grep D0
U _ZN3barD0Ev

$ ~/gcc/build/gcc/xgcc -B ~/gcc/build/gcc/ -c def.cpp -o def.o -O3 -flto -fPIC
$ ~/gcc/build/gcc/xgcc -B ~/gcc/build/gcc/ def.o -o def.so -shared
-fuse-linker-plugin
$ readelf  -sDW def.so | grep bar
  12   7: 0931 5 OBJECT  WEAK   DEFAULT  13 _ZTS3bar
  11  10: 1ca040 OBJECT  WEAK   DEFAULT  24 _ZTV3bar
  13  14: 1cd024 OBJECT  WEAK   DEFAULT  24 _ZTI3bar
   8  15: 08b010 FUNCGLOBAL DEFAULT  11 _ZN3bar3zedEv


Note that we have the vtable, but no the destructor.

$ g++ -shared -o foo.so undef.o def.so -Wl,-z,defs
undef.o:undef.cpp:function f(): error: undefined reference to 'bar::~bar()'


[Bug c++/52995] Change in the handling of templates and visibility attributes

2012-04-19 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52995

--- Comment #3 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2012-04-19 06:00:59 UTC ---
This just got discussed on the clang list. In the end we implemented what gcc
does. The winning argument was that it is not just the class that is templated,
but its members too. If a template argument can change the visibility of a
class, it should have the same power over its members.

My suggestion is to close this bug and mark it as working as intended, but I
will leave it open for the week in case someone else wants to comment.


[Bug c++/52995] New: Change in the handling of templates and visibility attributes

2012-04-15 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52995

 Bug #: 52995
   Summary: Change in the handling of templates and visibility
attributes
Classification: Unclassified
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: rafael.espind...@gmail.com


in
---
#define HIDDEN __attribute__((visibility(hidden)))
#define DEFAULT __attribute__((visibility(default)))

template class T struct HIDDEN A {
  static void DEFAULT bar();
};
struct HIDDEN H;
struct DEFAULT D;

void test() {
  AD::bar(); // default   
  AH::bar(); // hidden
}


gcc 4.5 would produce two default symbols (_ZN1AI1DE3barEv and
_ZN1AI1HE3barEv). Gcc 4.7 makes _ZN1AI1HE3barEv hidden.

I can't see why the hidden template argument should make AH more hidden
than AD.


[Bug c++/52995] Change in the handling of templates and visibility attributes

2012-04-15 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52995

--- Comment #2 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2012-04-15 12:28:44 UTC ---
(In reply to comment #1)
 http://gcc.gnu.org/gcc-4.7/changes.html
 The ELF symbol visibility of a template instantiation is now properly
 constrained by the visibility of its template arguments (bug c++/35688).

I agree that a hidden type H should make AH hidden. The problem with this
example is that A is already declared hidden. I can see an argument for both
_ZN1AI1DE3barEv and _ZN1AI1HE3barEv to be hidden or default, but it is really
strange to change only one of them.


[Bug tree-optimization/49911] SRA + DOM + VRP + -fstrict-enums incorrectly remove predicate

2011-09-07 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49911

--- Comment #22 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-09-07 14:58:57 UTC ---
Thanks!

 * testsuite/g++.dg/tree-ssa/pr49911.C: New test.

I think you forgot to add -fstrict-enums to the command line in the test.


[Bug tree-optimization/49911] SRA + DOM + VRP + -fstrict-enums incorrectly remove predicate

2011-09-05 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49911

--- Comment #19 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-09-05 17:14:29 UTC ---
 I've lost the track of whether anything else needs to be done to close
 this bug, though.  Should the patch be applied to the 4.6 and 4.5
 branches too (assuming it passes testing there)?

I would love to see this fixed in 4.5, as in there there is no
-fno-strict-enums to hide the bug in there.


[Bug c/50284] New: possible miscompilation with -fstrict-aliasing

2011-09-03 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50284

 Bug #: 50284
   Summary: possible miscompilation with -fstrict-aliasing
Classification: Unclassified
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: rafael.espind...@gmail.com


I am not sure if the attached program is valid, but I think it is covered by
c99 6.5 p7. On irc pinkia points out that it might be invalid. His arguments
are

* upcast is undefined in general, 6.5 p7 is trying to allow downcasting.
* upcasting is defined when the type was originally that type.

Two followup observations are that

* If we read z-data.XXX as an access to the member (an not the full
structure), all the access in the program are of the correct type.
* On the implementation side, this bug show up when main is in a another
translation unit too, a case where gcc could not know if the type was
originally that type.

Philip Taylor pointed me at
http://davmac.wordpress.com/2010/02/26/c99-revisited/ which has an interesting
discussion about Does accessing an object constitute access to the containing
object?

This bug is fixed on trunk by 160947, but since that is an optimization
change, it probably has just deactivated the code path that caused this
behavior.

For some context, this testcase is a reduction from:

http://hg.mozilla.org/mozilla-central/file/a351ae35f2c4/js/src/jscntxtinlines.h#l179


[Bug c/50284] possible miscompilation with -fstrict-aliasing

2011-09-03 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50284

--- Comment #1 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-09-03 18:53:58 UTC ---
Created attachment 25188
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=25188
testcase


[Bug c/50284] possible miscompilation with -fstrict-aliasing

2011-09-03 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50284

--- Comment #2 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-09-03 19:07:54 UTC ---
Forgot to mention, this only reproduces with -fPIC. So to reproduce this you
need

* a linux 32 bit build older than 160947
* run cc1 with: -quiet -fPIC -O2 -std=c99


[Bug c/50284] possible miscompilation with -fstrict-aliasing

2011-09-03 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50284

--- Comment #4 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-09-03 22:54:10 UTC ---
(In reply to comment #3)
 struct Value {
   struct jsval data;
 };
 ...
 struct jsval y = t3.array[i];
 struct Value *z = (struct Value*)y;
 if (z-data.tag == 0xFF85) {
 
 that's invalid in GCCs reading of 6.5 p7. jsval is a subset of Value's
 alias-set
 but not the other way around.  GCC reads z-data.tag as an access to an
 object of type Value which is invalid.

So downcast (i.e. casting to a more specialized type) are invalid even if
original data type is correct (not that it is in the reduced testcase)? That is
really strict :-(

 The contorted reasoning is that the pointer conversion invokes undefined
 behavior.  Definitely an interesting blog post ;)

is there any hope that gcc could be made a bit less strict? Either reading the
member access as not involving an access to the full object or accepting
downcasts (when the original type matches) would work. My preference would be
for the second option, as downcasts are fairly common in OO.


[Bug c/50284] possible miscompilation with -fstrict-aliasing

2011-09-03 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50284

Rafael Avila de Espindola rafael.espindola at gmail dot com changed:

   What|Removed |Added

  Attachment #25188|0   |1
is obsolete||

--- Comment #5 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-09-04 03:49:59 UTC ---
Created attachment 25189
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=25189
a better testcase

This one allocates the original objects as the derived class Value.


[Bug tree-optimization/49911] SRA + DOM + VRP + -fstrict-enums incorrectly remove predicate

2011-08-17 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49911

--- Comment #17 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-08-17 21:31:43 UTC ---
Created attachment 25041
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=25041
gcc 4.5 backport

I have tried porting the vrp patch to 4.5. It works out of the box on 32 bits,
but for 64 I had to backport the fix that sign extends size types too.


[Bug tree-optimization/49911] SRA + DOM + VRP + -fstrict-enums incorrectly remove predicate

2011-08-04 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49911

--- Comment #10 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-08-04 18:59:20 UTC ---
Created attachment 24919
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=24919
test patch

I ported 
http://gcc.gnu.org/ml/gcc-patches/2011-04/msg00741.html
to gcc 4.5 and was able to to build a working firefox in the environment that
mozilla's bots use.
Thanks!


[Bug tree-optimization/49911] vrp2 + -fstrict-enums incorrectly remove predicate

2011-07-31 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49911

--- Comment #2 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-07-31 13:38:54 UTC ---
I got it on 32 bit linux. Doing a git pull to check if it has just been fixed.


[Bug tree-optimization/49911] vrp2 + -fstrict-enums incorrectly remove predicate

2011-07-31 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49911

--- Comment #3 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-07-31 13:57:17 UTC ---
I was able to reproduce it on 176972. I did a 64 bit build on linux. It
reproduces with -m32, but not without.


[Bug tree-optimization/49911] New: vrp2 + -fstrict-enums incorrectly remove predicate

2011-07-30 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49911

   Summary: vrp2 + -fstrict-enums incorrectly remove predicate
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: rafael.espind...@gmail.com


with a r176947 cc1plus, running

cc1plus -fstrict-enums -fdump-tree-all ~/tmpfs/test2.ii -fno-rtti
-fno-exceptions -fno-strict-aliasing   -m32 -O2

in

extern  void JS_Assert();
typedef enum {
eax, ecx, edx, ebx, esp, ebp,
esi, edi }
RegisterID;
union StateRemat {
  RegisterID reg_;
  int offset_;
};
static StateRemat FromRegister(RegisterID reg) {
  StateRemat sr;
  sr.reg_ = reg;
  return sr;
}
static StateRemat FromAddress3(int address) {
  StateRemat sr;
sr.offset_ = address;
  //sr.offset_ = 0;
  if (address  46 address = 0) {
JS_Assert();
  }
  return sr;
}
struct FrameState {
  StateRemat dataRematInfo2(bool y, int z) {
if (y) return FromRegister(RegisterID(1));
return FromAddress3(z);
  }
};
FrameState frame;
StateRemat x;
void jsop_setelem(bool y, int z) {
  x = frame.dataRematInfo2(y, z);
}

produces a test2.ii.123t.vrp2 with:

Folding predicate SR.6_11 = 45 to 1

replacing the sr.offset_ = address line with sr.offset_ = 0 prevents the
transformation.


[Bug c/47980] New: Inefficient code for local const char arrays

2011-03-03 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47980

   Summary: Inefficient code for local const char arrays
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: rafael.espind...@gmail.com


gcc will compile


void f(const char *p);

void g(void) {
  const char foo[] = aoeuaoeuaeouaeouaoeuaoeaoxbxod;
  f(foo);
}
--

to

.cfi_startproc
subq$40, %rsp
.cfi_def_cfa_offset 48
movl$.LC0, %esi
movl$31, %ecx
leaq1(%rsp), %rdi
rep movsb
leaq1(%rsp), %rdi
callf
addq$40, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc

No idea why it wants to copy the string before calling f.


[Bug c/47980] Inefficient code for local const char arrays

2011-03-03 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47980

--- Comment #2 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-03-03 21:50:07 UTC ---
I agree that the code is correct. The bug is because of a missing optimization,
not about wrong behavior.

The only use of foo is passing it function expecting a const pointer. Gcc could
remove the copy and just pass a pointer to the global it created to hold the
string.

p.s.: how do I reopen the bug?


[Bug lto/47247] Linker plugin specification makes it difficult to handle COMDATs

2011-02-16 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47247

--- Comment #18 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-02-16 16:14:52 UTC ---
I have created a small test of the symbol table problem. It is in

http://people.mozilla.com/~respindola/test.tar.xz

The test is firefox's libxul with most files copied into one directory to make
it easy to run. The test script runs the link twice. First with the IL files
and then with combined .o file.

The sizes are

39339456 libxul1.so
34436696 libxul2.so

The output of size in both files is


For a 5 MB reduction I might end up writing a wrapper that runs ld twice :-)

232180682380480 2896682588821618b05d8libxul1.so
231754182380480 2896682584556618a5f3elibxul2.so


[Bug lto/47247] Linker plugin specification makes it difficult to handle COMDATs

2011-02-16 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47247

--- Comment #21 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-02-17 01:13:35 UTC ---
Most of it is in the string table. Ian gave me some pointers and I will try to
fix it tomorrow :-)


[Bug lto/47247] Linker plugin specification makes it difficult to handle COMDATs

2011-02-15 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47247

--- Comment #14 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-02-15 19:39:09 UTC ---
Sorry, can you expand on what gcc was doing that was causing it to expand the
dynamic symbol table?

With LLVM what we are doing is

*) Report all symbols
*) Any symbol not given a PREVAILING_DEF, we make it internal.
*) All other symbols stay the same.

For example, a vtable is normally produce as a symbol with linkonce_odr (see
http://llvm.org/docs/LangRef.html#linkage_linkonce_odr). If it is not used, we
drop it.

The potential problem with what LLVM is doing (I don't have a seem it in
practice, but haven't tried to force it) is the case

* file a.cc has the vtable for class foo and a use of it
* file b.cc has the vtable for class foo and a use of it

We produce IL for a.cc and a ELF for b.cc. Gold decides to use the IL version,
gives the plugin a PREVAILING_DEF. LLVM optimises the use away and drops the
vtable. We now have an undefined reference to the vtable.

With both PREVAILING_DEF_IRONLY_EXP and PREVAILING_DEF llvm would be able to
tell the difference. If there was no use of the vtable from an ELF file, gold
would give a PREVAILING_DEF_IRONLY_EXP and llvm would be allowed to drop it. If
there is, gold gives a PREVAILING_DEF and llvm must upgrade the vtable from
linkonce_odr to weak_odr which causes it to say in the final .o even if it
optimises out all uses.


[Bug lto/47247] Linker plugin specification makes it difficult to handle COMDATs

2011-02-15 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47247

--- Comment #16 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-02-16 04:03:36 UTC ---
 The problem is with dropping linkonce_odr that has been previously reported.
 This way gold will allocate entry in the dynamic symbol table (you can see it
 in
 nm of the final binary) with no definition/use.
 Once something is given PREVAILING_DEF, it can not be optimized away.

I see. Even with PREVAILING_DEF_IRONLY_EXP we still have to update gold to drop
those, no? Gold doesn't know the language semantics to know which visible
symbols can or cannot be dropped, so it can only assume the plugin knows what
it is doing when it drops one.

  We produce IL for a.cc and a ELF for b.cc. Gold decides to use the IL 
  version,
  gives the plugin a PREVAILING_DEF. LLVM optimises the use away and drops the
  vtable. We now have an undefined reference to the vtable.
 
 Yes, that is problem, too, but I didn't see it in practice.

Yes, the common case is to try to put as much as possible in the IL :-)
Now that I can build firefox in LTO I will try to create a testcase for this
next week.

  
  With both PREVAILING_DEF_IRONLY_EXP and PREVAILING_DEF llvm would be able to
  tell the difference. If there was no use of the vtable from an ELF file, 
  gold
  would give a PREVAILING_DEF_IRONLY_EXP and llvm would be allowed to drop 
  it. If
  there is, gold gives a PREVAILING_DEF and llvm must upgrade the vtable from
  linkonce_odr to weak_odr which causes it to say in the final .o even if it
  optimises out all uses.
 
 Yes, that seems right except that GCC makes difference in between comdat
 symbols that must stay even if they are optimized out and weak symbols since
 both are handled bit differently.  I am not sure if updating comdat symbol to
 weak is safe in ELF world, probably Iant would know.

Well, since we know this is the symbol being used, llvm can just upgrade it all
the way to a regular symbol.

 Honza

Thanks,
Rafael


[Bug lto/47247] Linker plugin specification makes it difficult to handle COMDATs

2011-02-14 Thread rafael.espindola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47247

--- Comment #12 from Rafael Avila de Espindola rafael.espindola at gmail dot 
com 2011-02-14 19:59:22 UTC ---
A quick summary to see if got this right:

Currently the linker has three options for a symbol in a comdat:

*) pick one not in the IL. The plugin gets a PREEMPTED_REG
*) pick one in the IL and give PREVAILING_DEF to the plugin
*) as above, but PREVAILING_DEF_IRONLY

The first one is undesirable since the more LTO sees, the better.
The second one prevents gcc from dropping tho symbol if it drops the uses.
To give the third option the plugin would have to know the semantics of this
symbol (available anywhere it is used).

The proposal is that PREVAILING_DEF_IRONLY_EXP will let gcc drop all references
if it drops all uses.

Some cases:

*) a visible symbol in IL and there is a reference from it in a ELF file. Gold
must give PREVAILING_DEF to the plugin and it cannot drop it.
*) a visible symbol in IL and there is no references from it in a ELF file.
Gold gives PREVAILING_DEF_IRONLY_EXP to the plugin. What gcc can do then
depends on what the symbol is
  1) if the symbol is one (like vtable) known to be available where it is
needed, gcc can drop it if it drops all uses
  2) if the symbol is a simple weak symbol gcc must keep it
*) a local symbol. gold gives PREVAILING_DEF_IRONLY to the plugin and it can do
anything it wants with it.

On LLVM land I think this translates to

*) If given PREVAILING_DEF, linkonce gets upgrade to weak and linkonce_odr to
weak_odr
*) If given PREVAILING_DEF_IRONLY_EXP, likages stay as they are
*) If given PREVAILING_DEF_IRONLY the symbol gets internalized

I think this should work, thanks.