https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84083
Bug ID: 84083 Summary: [missed optimization] loop-invariant strlen() not hoisted out of loop Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: eyalroz at technion dot ac.il Target Milestone: --- Consider the following code: #include <string.h> void bar(char c); void foo(const char* __restrict__ ss) { for (int i = 0; i < strlen(ss); ++i) { bar(*ss); } } To my understanding, the fact that ss is __restrict__ed (and the fact that it isn't written through or that it's a const pointer) is sufficient to allow the compiler to assume the memory accessible via ss remains constant, and thus that strlen(ss) will return the same value. But - that's not what happens (with GCC 7.3): .L6: movsx edi, BYTE PTR [rbp+0] mov rbx, r12 call bar(char) .L3: mov rdi, rbp lea r12, [rbx+1] call strlen cmp rax, rbx ja .L6 (obtained with https://godbolt.org/g/vdGSBe ) Now, I'm no compiler expert, so maybe there are considerations I'm ignoring, but it seems to me the compiler should be able to hoist the heavier code up above the loop. Cf. https://stackoverflow.com/q/48482003/1593077