https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- >From what I can see, the warning is on dead code. <bb 2> [local count: 1073741824]: MEM[(struct _State_base *)&__tmp] ={v} {CLOBBER}; MEM[(struct _State_base *)&__tmp]._M_opcode = 9; MEM[(struct _State_base *)&__tmp]._M_next = -1; _12 = MEM[(long unsigned int * const &)this_3(D) + 8]; _1 = MEM[(value_type &)_12 + 18446744073709551608]; __tmp.D.93077.D.69952._M_subexpr = _1; _11 = _12 + 18446744073709551608; MEM[(struct vector *)this_3(D)].D.71153._M_impl.D.70460._M_finish = _11; MEM[(struct _State *)&D.93141] ={v} {CLOBBER}; MEM[(struct _State *)&D.93141].D.93077 = MEM[(struct _State &)&__tmp].D.93077; _43 = MEM[(const struct _State *)&__tmp].D.93077._M_opcode; if (_43 == 11) goto <bb 3>; [34.00%] else goto <bb 23>; [66.00%] <bb 23> [local count: 708669600]: goto <bb 5>; [100.00%] <bb 3> [local count: 365072224]: MEM[(struct function *)&D.93141 + 16B] ={v} {CLOBBER}; MEM[(struct function *)&D.93141 + 16B].D.69910 = {}; _44 = MEM[(struct function &)&__tmp + 16]._M_invoker; MEM[(struct function *)&D.93141 + 16B]._M_invoker = _44; __tmp has: struct _State_base { protected: _Opcode _M_opcode; // type of outgoing transition public: _StateIdT _M_next; // outgoing transition union // Since they are mutually exclusive. { size_t _M_subexpr; // for _S_opcode_subexpr_* size_t _M_backref_index; // for _S_opcode_backref struct { // for _S_opcode_alternative, _S_opcode_repeat and // _S_opcode_subexpr_lookahead _StateIdT _M_alt; // for _S_opcode_word_boundary or _S_opcode_subexpr_lookahead or // quantifiers (ungreedy if set true) bool _M_neg; }; // For _S_opcode_match __gnu_cxx::__aligned_membuf<_Matcher<char>> _M_matcher_storage; }; type where _StateIdT is some pointer and _M_matcher_storage is 32 bytes large, the union is at offset 16. Now, bb 2 initializes it to be _M_opcode 9 (aka _S_opcode_subexpr_end) with the _M_subexpr as active union field (so everything but the first 8 bytes of the union are uninitialized). But at the end of the bb we test _M_opcode against 11 (aka _S_opcode_match) and if it is that value, we extract std::function's _M_invoker (which is a pointer at offset 16 bytes into the union). So obviously it is uninitialized but dead. At -O1 we don't do PRE, but I wonder why fre3 doesn't optimize this. <bb 2> [local count: 1073741824]: MEM[(struct _State_base *)&__tmp] ={v} {CLOBBER}; MEM[(struct _State_base *)&__tmp]._M_opcode = 9; MEM[(struct _State_base *)&__tmp]._M_next = -1; _12 = MEM[(long unsigned int * const &)this_3(D) + 8]; _1 = MEM[(value_type &)_12 + 18446744073709551608]; __tmp.D.93077.D.69952._M_subexpr = _1; _11 = _12 + 18446744073709551608; MEM[(struct vector *)this_3(D)].D.71153._M_impl.D.70460._M_finish = _11; MEM[(long unsigned int *)_12 + -8B] ={v} {CLOBBER}; MEM[(struct _State *)&D.93141] ={v} {CLOBBER}; MEM[(struct _State *)&D.93141].D.93077 = MEM[(struct _State &)&__tmp].D.93077; _43 = MEM[(const struct _State *)&__tmp].D.93077._M_opcode; if (_43 == 11) there are 3 stores into __tmp, one to offset 0 4 bytes _M_opcode = 9, one to offset 8 8 bytes _M_next = -1 and one to offset 16 8 bytes _M_subexpr = _1, it doesn't seem like other stores could alias with that, so why don't we optimize _43 = 9; ?