If there are any internal methods whose address was taken, conclude there is nothing known in relation of any other internal method and a global.
I think this version of the test case is slightly oversimplified and it would be valid for an optimisation to remove the check. If there is any address-taken function that may have escaped, then it is not okay to assume that @llvm.objc.autoreleasePoolPop will definitely not write to it, but in this case there are no stores to an internal global and so GVN is at liberty to eliminate it entirely. The fact that it doesn't is a missed optimisation caused by not having sufficient knowledge of @llvm.objc.autoreleasePoolPop.
In the original version of the test case, the miscompile comes from the fact that a -dealloc method stores to deallocCalled. The -dealloc method is registered with the runtime and is in a data structure that visible to the runtime.
I updated the patch to be more generic, while still addressing this usecase.
The condition is: if there are any internal methods whose address is taken but for which we do not conclude that they do not modify globals, then cannot conclude lower than ModRef for any other (LocalLinkageCall, GlobalValue).
Do I understand correctly that this going to be conservative in the case the internal function with its address taken is readonly/none?
Either way, could we have a test for that to make sure we see the "good" behavior or a FIXME in the code and test explaining what is needed?