> memory-based optimizations should not be permitted when two pointers have been converted to/from integers.
Just to be clear, what you are saying is that it is not legal to transform this function:
int foo() {
int x = 5;
bar();
return x;
}
into this function:
int foo_opt() {
bar();
return 5;
}
And the end result of disallowing that kind of optimization is that effectively any function that transitively calls an unknown external function [1] gets -O0 performance. Note that one of the memory optimizations is moving values from memory to registers, which is an effective prerequisite of virtually every useful optimization, including the bread-and-butter optimizations that provide multiple-× speedups.
I suspect many people--including you--would find such a semantics to have too wide a blast radius. And if you start shrinking the blast radius, even to include such "obvious cases" as address-not-taken, you introduce some notion of pointer provenance.
That's how we arrived at the current state. We've given everything the "obvious" semantics, including making the "obvious" simplifying assumptions (such as address-not-taken not being addressable by pointers). But we have discovered--and this took decades to find out, mind you--that using "obvious" semantics causes contradictions [2].
Take a look at the quiz that prompted this discussion: <https://www.cl.cam.ac.uk/~pes20/cerberus/notes50-survey-disc...> and <https://www.cl.cam.ac.uk/~pes20/cerberus/notes30.pdf>. There's a lot of cases where pointer provenance crops up that asking C experts "does this work" or "should this work" ends up with head-scratching. Indeed, if you compare several claimed formal semantics of C, there are several cases where they disagree.
[1] An unknown external function must be assumed to do anything that it is legal to do, so a compiler is forced to assume that it is converting pointers to/from integers. And if that is sufficient to prohibit all memory-based optimizations, then it follows that calling an unknown external function is sufficient to prohibit all memory-based optimizations.
[2] And just to be clear, this isn't "this is breaking new heroic optimizations we're creating today", this is a matter of "30-year-old C compilers aren't compiling this code correctly under these semantics."
Just to be clear, what you are saying is that it is not legal to transform this function:
into this function: And the end result of disallowing that kind of optimization is that effectively any function that transitively calls an unknown external function [1] gets -O0 performance. Note that one of the memory optimizations is moving values from memory to registers, which is an effective prerequisite of virtually every useful optimization, including the bread-and-butter optimizations that provide multiple-× speedups.I suspect many people--including you--would find such a semantics to have too wide a blast radius. And if you start shrinking the blast radius, even to include such "obvious cases" as address-not-taken, you introduce some notion of pointer provenance.
That's how we arrived at the current state. We've given everything the "obvious" semantics, including making the "obvious" simplifying assumptions (such as address-not-taken not being addressable by pointers). But we have discovered--and this took decades to find out, mind you--that using "obvious" semantics causes contradictions [2].
Take a look at the quiz that prompted this discussion: <https://www.cl.cam.ac.uk/~pes20/cerberus/notes50-survey-disc...> and <https://www.cl.cam.ac.uk/~pes20/cerberus/notes30.pdf>. There's a lot of cases where pointer provenance crops up that asking C experts "does this work" or "should this work" ends up with head-scratching. Indeed, if you compare several claimed formal semantics of C, there are several cases where they disagree.
[1] An unknown external function must be assumed to do anything that it is legal to do, so a compiler is forced to assume that it is converting pointers to/from integers. And if that is sufficient to prohibit all memory-based optimizations, then it follows that calling an unknown external function is sufficient to prohibit all memory-based optimizations.
[2] And just to be clear, this isn't "this is breaking new heroic optimizations we're creating today", this is a matter of "30-year-old C compilers aren't compiling this code correctly under these semantics."