https://godbolt.org/z/hdWKn4bjc All three functions write to the same variable (b). Clang is able to optimize this. GCC -O3 cannot always do this. Assembly for foo is writing to **d instead to directly write 1 to b. There is similar behavior for bar and baz. Clang optimizes the code to directly write to b. Baz is fully optimized only if the foo and bar are removed. int b = 0; static int *c = &b; static int **d = &c; static int ***e = &d; void foo() {***e = 1;} void bar() {**d = 1;} void baz() {*c = 1;} Assembly code: foo: movq d(%rip), %rax movq (%rax), %rax movl $1, (%rax) ret
Yes gcc static read only pass does not cycle . So it only able to remove currently one level of indirection.
Cycling read-only var discovery would be quite expensive, since you need to interleave it with early opts each round. I wonder how llvm handles this? I think there is more hope with IPA-PTA getting scalable version at -O2 and possibly being able to solve this.