[Bug ipa/68470] [4.9/5/6 Regression] Internal Compiler Error observed by g++-4.9.2 and a few other versions (reported to Debian)
marxin at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Nov 23 13:39:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68470
Martin Liška <marxin at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |marxin at gcc dot gnu.org
--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> ---
(In reply to Mikhail Maltsev from comment #3)
> A bit simplified testcase:
>
> void deallocate(void *);
> void *a;
>
> struct C {
> virtual void m_fn1();
> };
>
> struct D {
> C *m_fn2() {
> if (a)
> __builtin_abort();
> }
> };
> D getd();
>
> struct vec_int {
> int _M_start;
> ~vec_int() {
> if (_M_start)
> deallocate(&_M_start);
> }
> };
> vec_int *b;
>
> struct I {
> virtual void m_fn3();
> };
>
> void I::m_fn3() {
> if (a)
> getd().m_fn2()->m_fn1();
> b->~vec_int();
> }
>
> $ cc1plus -O2 test.cc - ICE after fnsplit
> $ cc1plus -O2 test.cc -fno-checking - ICE in IPA-ICF (like in the original
> bug report)
> $ cc1plus -O2 test.cc -fno-devirtualize - OK
> $ cc1plus -O2 test.cc --param partial-inlining-entry-probability=0 - OK
>
> ISTM, this is some IPA-related issue:
> D::m_fn2 and vec_int::~vec_int are inlined into I::m_fn3.
> D::m_fn2 (D::operator-> in previous comments) does not return any value
> (undefined behavior), so gimple_fold_call devirtualizes
> getd().m_fn2()->m_fn1() into __builtin_unreachable during fwprop1.
> fnsplit then tries to split I::m_fn3. This is how the function looks before
> fnsplit:
>
> ;; Function virtual void I::m_fn3() (_ZN1I5m_fn3Ev, funcdef_no=4,
> decl_uid=2299, cgraph_uid=4, symbol_order=6)
>
> virtual void I::m_fn3() (struct I * const this)
> {
> struct C * D.2356;
> void * a.0_3;
> void * a.2_5;
> struct vec_int * b.1_12;
> int _14;
> int * _15;
>
> <bb 2>:
> a.0_3 = a;
> if (a.0_3 != 0B)
> goto <bb 3>;
> else
> goto <bb 6>;
>
> <bb 3>:
> getd ();
> a.2_5 = a;
> if (a.2_5 != 0B)
> goto <bb 4>;
> else
> goto <bb 5>;
>
> <bb 4>:
> __builtin_abort ();
>
> <bb 5>:
> __builtin_unreachable ();
>
> <bb 6>:
> b.1_12 = b;
> _14 = b.1_12->_M_start;
> if (_14 != 0)
> goto <bb 7>;
> else
> goto <bb 8>;
>
> <bb 7>:
> _15 = &b.1_12->_M_start;
> deallocate (_15);
>
> <bb 8>:
> MEM[(struct &)b.1_12] ={v} {CLOBBER};
> return;
>
> }
>
> The splitting pass tries to do this:
>
> Splitting function at:
> Split point at BB 6
> header time: 19646 header size: 10
> split time: 2491 split size: 6
> bbs: 6, 7
> SSA names to pass:
> Introduced new external node (void __builtin_unreachable()/18).
>
> ICE probably happens in this part:
>
> virtual void I::m_fn3() (struct I * const this)
> {
> struct C * D.2356;
> void * a.0_3;
> void * a.2_5;
>
> <bb 2>:
> a.0_3 = a;
> if (a.0_3 != 0B)
> goto <bb 3>;
> else
> goto <bb 6>;
>
> <bb 3>:
> getd ();
> a.2_5 = a;
> if (a.2_5 != 0B)
> goto <bb 4>;
> else
> goto <bb 5>;
>
> <bb 4>:
> __builtin_abort ();
>
> <bb 5>:
> __builtin_unreachable ();
>
> <bb 6>:
> I::_ZN1I5m_fn3Ev.part.1 ();
> MEM[(struct &)_12] ={v} {CLOBBER};
> return;
>
> }
Hi.
The problem is really in <bb 6>, which contains definition of 'b.1_12' that is
used in return_bb (<bb 8>). The return_bb is eventually merged with <bb 6>.
I'm not sure about proper fix, I would expect that return_bb must be pruned of
all unused stmts (that would be moved to newly created function). Any ideas?
Martin
More information about the Gcc-bugs
mailing list