https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84658
--- Comment #14 from Martin Liška <marxin at gcc dot gnu.org> --- (In reply to Richard Biener from comment #13) > So you can loses the TREE_ADDRESSABLE restriction somewhat in requiring at > most one decl to be TREE_ADDRESSABLE - that's the one you need to keep, the > others may become aliases. Given TREE_ADDRESSABLE isn't reliable for > !TREE_STATIC vars > we can't merge any exported decls that way. Consider > > const int foo1; > const int foo2; > > int *bar(); // in other TU, returns address of foo1 > > int main () > { > if (bar() != &foo2) > ...; > } > > not sure if we want to do hand-waving saying that we can't possibly have > points-to sets mentioning those without seeing the function IL. Well, > might be similarly hand-waving as the reference aliasing issue. > > So we could drop the TREE_STATIC restriction if TREE_ADDRESSABLE is reliable > within the current TU. Note that this issue happens only with -fmerge-all-constants. And we have caveat in documentation that using the option, pointer comparison can be broken: Languages like C or C++ require each variable, including multiple instances of the same variable in recursive calls, to have distinct locations, so using this option results in non-conforming behavior. Thus: $ cat test.c const int foo1 = 3; const int foo2 = 3; const int * __attribute__((noinline)) bar() { return &foo1; } int main () { if ((bar() - &foo2) == 0) __builtin_abort (); return 0; } $ gcc test.c -O2 -fno-ipa-icf -fmerge-all-constants && ./a.out Aborted (core dumped) That said, would be Richi your comment in c#12 a sufficient fix?