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.

Reply via email to