https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70018
Bug ID: 70018 Summary: Possible issue around IPO and C++ inline functions Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: sanjoy at playingwithpointers dot com Target Milestone: --- I don't grok gcc internals so I cannot write a terribly well-informed bug report, but GCC 5.3.0 seems to miscompile https://github.com/sanjoy/comdat-ipo This was discussed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2016-February/095833.html and the thread contains a description of the underlying cause for LLVM/Clang. The TL;DR is that for C++ inline functions (and other functions with similar linkage rules), you can override a more-refined function implementation with a less-refined one at link time, and that can retroactively invalidate earlier transforms, where "refined" in this case means "undefined in fewer situations". E.g. if we have (this is very similar to the reproducer above minus some mechanical details): inline void foo(int* ptr) { 100 / ptr[0]; } void bar(int* ptr) { *ptr = 40; foo(ptr): *ptr = 50; } => inline void foo(int* ptr) { // 100 / ptr[0]; removed, dead code } void bar(int* ptr) { *ptr = 40; foo(ptr): *ptr = 50; } => inline void foo(int* ptr) { // 100 / ptr[0]; removed, dead code } void bar(int* ptr) { // *ptr = 40; dead store, since foo does not read memory foo(ptr): *ptr = 50; } we've miscompiled if *ptr == 0 on entry to bar, and foo is replaced with the original definition at link time.