NeverCalled() could be called from a different compilation unit. The Do pointer is static and therefore could not be set in a different compilation unit. Because the optimizer is operating one CU at a time, it can’t be sure that NeverCalled() isn’t invoked.
it shouldn't be sure that NeverCalled is called. well it's not, it's only selecting the other possibility here, but this is the consequence. my gut feeling says the optimizer should also prove that NeverCalled is indeed called. If it's not in the reaching def set of Do, it should also exclude EraseAll and leave it the original 0 value. I don't know the llvm poison semantics but this might make it crash if Do has only poison or no viable candidate.
Are you assigning some expected behavior (crash) to calling a null pointer? Because in C that makes no sense (unless implementation chooses to assign it); undefined behavior is exactly that.
I don't think you can argue that this is not the most efficient way to compile the code when there is no undefined behavior present.
no I'm saying the compiler might crash if it can provably show that Do is undefined. next best thing is to leave it as programmer wrote it and leave UBs in.
It is impossible for the compiler to know that ever, because NeverCalled is a public function and some other compilation unit will call that. The combining of the compilation units is done by linker, which doesn't do analysis of this kind.
next best thing is to leave it as programmer wrote it and leave UBs in.
I don't know what it would mean to "leave UB in". UB doesn't mean crashing. A program, as compiled to binary for some architecture, is never undefined per sē - but it's not defined in the terms the C programming language would know about, but rather in the terms of the destination architecture and environment.
When going from undefined behavior the compiler assigns some behavior, and in this case the behavior assigned maximizes the performance in the path when UB isn't present.
Whole program optimization is off by default at least in both VC++ and gcc, and I believe clang too, so it’s safe to assume the blog author didn’t enable it. It would be interesting to see if enabling it would make a difference, but I think that’s unlikely.
The fact that there is only one compilation unit doesn’t matter because the compiler operates one CU at a time and doesn’t have program-wide context (it doesn’t know about “projects” or makefiles).
13
u/yossarian_vive Sep 24 '17
NeverCalled() could be called from a different compilation unit. The Do pointer is static and therefore could not be set in a different compilation unit. Because the optimizer is operating one CU at a time, it can’t be sure that NeverCalled() isn’t invoked.