https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77692
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Ok, so tree_add_const_value_attribute_for_decl gives up because the decl is not readonly. But via add_location_or_const_value_attribute rtl_for_decl_location would get us (const_vector:V4SF [ (const_double:SF 2.5e+8 [0x0.ee6b28p+28]) (const_double:SF 0.0 [0x0.0p+0]) (const_double:SF 0.0 [0x0.0p+0]) (const_double:SF 0.0 [0x0.0p+0]) ]) which looks inconsistent. That simply does /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time constant, and will have been substituted directly into all expressions that use it. C does not have such a concept, but C++ and other languages do. */ if (!rtl && TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl)) rtl = rtl_for_decl_init (DECL_INITIAL (decl), TREE_TYPE (decl)); which may be true if called late enough. We're invoking dwarf2out_late_global_decl for removed globals only at a very specific point so it doesn't get called for typedef float FloatVect __attribute__((__vector_size__(16))); static FloatVect Foo = { 250000000.0, 0.0, 0.0, 0.0 }; int main() { Foo = (FloatVect) { 1., 1., 1., 1. }; } where we also remove Foo (as write-only). For this case it would be definitely bogus to add a DW_AT_const_value attribute. We do call it for typedef float FloatVect __attribute__((__vector_size__(16))); static FloatVect Foo = { 250000000.0, 0.0, 0.0, 0.0 }; static void bar () { Foo = (FloatVect) { 1., 1., 1., 1. }; } int main() { } which means this case did get a DW_AT_const_value attached to Foo. Note that on the original testcase IPA would have found Foo to be readonly, likewise on the last. I believe rtl_for_decl_location is bogus doing /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time constant, and will have been substituted directly into all expressions that use it. C does not have such a concept, but C++ and other languages do. */ if (!rtl && TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl)) rtl = rtl_for_decl_init (DECL_INITIAL (decl), TREE_TYPE (decl)); when it is called early before decl got a chance to even create RTL. So -- is it worth trying to handle this special case where we know a variable is readonly by means of nothing referencing it? Then the following fixes it: Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 240388) +++ gcc/cgraphunit.c (working copy) @@ -1194,8 +1194,15 @@ analyze_functions (bool first_time) at looking at optimized away DECLs, since late_global_decl will subsequently be called from the contents of the now pruned symbol table. */ - if (!decl_function_context (node->decl)) - (*debug_hooks->late_global_decl) (node->decl); + if (TREE_CODE (node->decl) == VAR_DECL + && !decl_function_context (node->decl)) + { + /* We are reclaiming totally unreachable code and variables + so they effectively appear as readonly. Show that to + the debug machinery. */ + TREE_READONLY (node->decl) = 1; + (*debug_hooks->late_global_decl) (node->decl); + } node->remove (); continue;