https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99046
Bug ID: 99046 Summary: [[gnu::const]] function needs noexcept to be recognized as loop invariant Product: gcc Version: 10.2.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: glisse at gcc dot gnu.org Target Milestone: --- (from https://stackoverflow.com/q/66100945/1918193) double x[1000] = {}; [[gnu::const]] double* g(double* var); void f() { for (int i = 1; i < 1000; i++) { g(x)[i] = (g(x)[i-1] + 1.0) * 1.001; } } g++ -O3 eliminates half of the calls to g, but fails to move it to a single call before the loop, while llvm does just that. Gcc does manage it if I mark f as noexcept or nothrow. Whether const functions may throw seems debatable, but if they do throw, I expect them to do so consistently, and since the loop has at least one iteration and starts with this call, the transformation seems safe to me.