genmatch infinite loop during bootstrap on AIX

David Edelsohn dje.gcc@gmail.com
Wed Oct 29 13:23:00 GMT 2014


On Wed, Oct 29, 2014 at 8:26 AM, Richard Biener <rguenther@suse.de> wrote:
> On Fri, 24 Oct 2014, David Edelsohn wrote:
>
>> genmatch is hanging when bootstrapping on AIX (gcc111).  When I attach
>> to the process:
>>
>> #0  0x1007efac in std::basic_string<char, std::char_traits<char>,
>> std::allocator<char> >::basic_string ()
>> #1  0x1000e6b0 in _ZN6parser13parse_captureEP7operand (this=0x300594b8, op=0x0)
>>     at /home/dje/src/src/gcc/genmatch.c:2607
>> #2  0x1000e9f0 in _ZN6parser10parse_exprEv (this=0x2ff20208)
>>     at /home/dje/src/src/gcc/genmatch.c:2669
>> #3  0x1000ee38 in _ZN6parser8parse_opEv (this=0x2ff20208)
>>     at /home/dje/src/src/gcc/genmatch.c:2728
>> #4  0x1000efc4 in
>> _ZN6parser14parse_simplifyEjR3vecIP8simplify7va_heap6vl_ptrEP12predicate_idP4expr
>> (this=0x2ff20208, match_location=4614, simplifiers=...,
>>     matcher=0x0, result=0x0) at /home/dje/src/src/gcc/genmatch.c:2792
>> #5  0x100102fc in _ZN6parser13parse_patternEv (this=0x2ff20208)
>>     at /home/dje/src/src/gcc/genmatch.c:3052
>> #6  0x10010c0c in _ZN6parser9parse_forEj (this=0x2ff20208)
>>     at /home/dje/src/src/gcc/genmatch.c:2991
>> #7  0x10010350 in _ZN6parser13parse_patternEv (this=0x2ff20208)
>>     at /home/dje/src/src/gcc/genmatch.c:3090
>> #8  0x1001122c in _ZN6parserC2EP10cpp_reader (this=0x2ff20208, r_=0x3003bbec)
>>     at /home/dje/src/src/gcc/genmatch.c:3122
>> #9  0x10004acc in main (argc=<error reading variable>,
>>     argv=<error reading variable>) at  _start_ :3204
>
> (I've re-built stage2 build/genmatch with -g, thus no optimization
> and debug info)
>
> Then I see a different frame #0 (std::allocator<char>::allocator()) and
> for frame #1 I see
>
>    0x100098b4 <+160>:   stw     r9,88(r31)
>    0x100098b8 <+164>:   lwz     r9,152(r31)
>    0x100098bc <+168>:   lwz     r30,12(r9)
>    0x100098c0 <+172>:   addi    r9,r31,64
>    0x100098c4 <+176>:   mr      r3,r9
>    0x100098c8 <+180>:   bl      0x100984dc <_ZNSaIcEC1Ev>
> => 0x100098cc <+184>:   lwz     r2,20(r1)
>
> while for _ZNSaIcEC1Ev there doesn't seem to be proper debug information
> (maybe I'm missing some tricks for that) even though stage1 libstdc++
> was built with -g.  The dissassembly of this (empty!) constructor
> looks completely weird though:
>
> (gdb) down
> #0  0x100984dc in std::allocator<char>::allocator() ()
> (gdb) disassemble
> Dump of assembler code for function _ZNSaIcEC1Ev:
> => 0x100984dc <+0>:     addi    r12,r2,-9528
>    0x100984e0 <+4>:     stw     r2,20(r1)
>    0x100984e4 <+8>:     lwz     r0,0(r12)
>    0x100984e8 <+12>:    lwz     r2,4(r12)
>    0x100984ec <+16>:    mtctr   r0
>    0x100984f0 <+20>:    bctr
>    0x100984f4 <+24>:    .long 0x0
>    0x100984f8 <+28>:    .long 0xca000
>    0x100984fc <+32>:    .long 0x0
>    0x10098500 <+36>:    .long 0x18
> End of assembler dump.

bctr is the end of the function.  It is an unconditional, indirect
jump, likely a tail call.

The instructions after the bctr are part of the function epilogue on
AIX with information about the function, originally for AIX exception
handling and stack walking, not used by GCC EH.

>
> 'bctr' seems to be a jump to $r0 (0x100984dc) here and all other
> instructions are fancy no-ops?  I do see a long list of warnings
> at link time similar to
>
> ld: 0711-768 WARNING: Object
> /home/rguenth/obj/prev-powerpc-ibm-aix7.1.0.0/libst
> dc++-v3/src/.libs/libstdc++.a[libstdc++.so.6], section 1, function
> .std::time_ge
> t<wchar_t, std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> >
>>::_M_e
> xtract_via_format(std::istreambuf_iterator<wchar_t,
> std::char_traits<wchar_t> >,
>  std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> >,
> std::ios_base&,
> std::_Ios_Iostate&, tm*, wchar_t const*) const:
>         The branch at address 0x10042638 is not followed by a recognized
> no-op
>         or TOC-reload instruction. The unrecognized instruction is
> 0x4BFFFEBC.
>
> so maybe some weird PPC stuff is not set up correctly in libstdc++
> so that the above function doesn't compute its return address
> correctly.

Those warnings are normal.  GCC is generating a tail call to a global
function that it knows is in the same translation unit
(binds_local_p).  Depending on how one interprets SVR4 ABI, one should
be able to interpose the call, which could call a function external to
the TU. AIX (and PPC64 BE) require a nop instruction after calls to
global functions that can be replaced with an instruction to restore
the TOC (GOT) if the call is determined to reference a function in
another TU at link-edit time.  The instruction is not followed by the
no-op, so the AIX linker complains.  It's basically complaining that
GCC is being too aggressive in optimization -- tail call to global
function in same source file -- but it's not a bug.

> Maybe we only run into this because genmatch is the first and only
> generator program that actually uses libstdc++ and we don't do
> well using a libstdc++ built with -g only (and no optimization).
> This is after all the very first entry into libstdc++ (to an
> empty function).
>
> I am making the bootstrap continue by copying over stage1 genmatch.
> Let's see if stage3 fails the same way (it should use the optimized
> libstdc++ from stage2).

Why would genmatch have problems while cc1 and cc1plus do not?

Thanks, David



More information about the Gcc-patches mailing list