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: