This patch is a bit subtle.
Let's start with the transform we'd like to do, but can't. If we have two malloc'd objects, we'd like to be able to say that their addresses are not equal (unless null). However, we can't do this as while the two memory objects don't *alias*, one of them might have been freed and the allocator is allowed to reuse storage.
However, for a language with a garbage collector, we know that this storage reuse is (by definition) invisible in the source program. During lowering there's a point where reuse becomes possible, but while the program is targeting the abstract machine model and using nonintegral pointers, that reuse isn't visible.
(Side note: The current wording on nonintegral makes it unclear whether comparing two non-integral pointers is merely in-determinant, or something stronger like returning poison. This patch doesn't care, but it does look like we have some wording to refine.)
I *think* such a GC allocation must also overlap with byval arguments, allocas, and globals, but I'm leaving that to a follow up patch. (In particular, the dynamic alloca + gc_alloc + dead code case has me a bit hesitant.)