[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#781060: g++-4.9: Broken optimization when move-constructing from virtual subclass



On Tue, Mar 24, 2015 at 10:20:20AM -0700, Kenton Varda wrote:
> My hunch is that GCC is incorrectly deciding that the modifications to
> the source object don't matter, perhaps because it's a temporary that
> will be destroyed shortly anyway and GCC incorrectly decides that D's
> destructor is trivial. It seems to be affected by the presence of
> virtual inheritance.

I digged a bit.  The code is still in there after the "Value range
propagation" pass:

|   struct D D.2804;
|   bool _10;
| 
|   D.2804 = {};
| [...]
|   MEM[(struct A &)&D.2804 + 8].moved = 1;
| [...]
|   _10 = MEM[(struct A *)&D.2804 + 8B].moved;
|   if (_10 != 0)

After the first "Dead code elimination" it's gone:

|   struct D D.2804;
|   bool _10;
| 
|   MEM[(struct C *)&D.2804] ={v} {CLOBBER};
|   _10 = MEM[(struct A *)&D.2804 + 8B].moved;
|   if (_10 != 0)

Let's try disabling this pass:

| $ g++ -o test test.cpp -Wall -W -std=c++11 -O2 -fdisable-tree-dce1           
| cc1plus: note: disable pass tree-dce1 for functions in the range of [0, 4294967295]
| $ ./test                                                          
| ~A(): moved = true
| ~A(): moved = false

Let's try with 4.8.  Wow, this looks completely different.  4.8 managed
to get rid of the whole block way earlier in the optimization.  (4.9
refuses to inline D::~D(), because it is too large).

Bastian

-- 
Conquest is easy. Control is not.
		-- Kirk, "Mirror, Mirror", stardate unknown


Reply to: