Currently SCEVExpander creates inttoptr for non-integral pointers if the
base is a null constant for example. This results in invalid IR.
This patch changes InsertNoopCastOfTo to emit a GEP to convert to a
non-integral pointer. The GEP uses null as base. The original value is
converted to an index by dividing by the alloc size of the type.
Note that this requires the original value to be divisible by the alloc
size, otherwise the pointer value will be changed. I am not sure if that
is an issue in practice (ideally the expander would only be used for
expanding pointer arithmetic that keeps the result divisible by the
alloc size) and there is not much we could do otherwise.
I guess we could instead try to create a pointer with alloc size of 1
byte, create a GEP with the original value as index and bitcast to the
target type. I am not sure if we can always do that, but I guess we
could add an assertion if that happens.
This was exposed by D71539.
It's probably worth noting the reason we know this is safe. Semantically, a GEP from null is quite different from an inttoptr: a GEP from null can't be used to access memory. I guess the reason this is safe is that we know the original IR must also have been a GEP from null.