I was looking at some missed optimizations in CHERI-enabled targets and
noticed that we weren't removing vtable indirection for calls via known
pointers-to-members. The underlying reason for this is that we represent
pointers-to-function-members as {i8 addrspace(200)*, i64} and generate the
constant offsets using (gep i8 null, <index>). We use a constant GEP here
since inttoptr should be avoided for CHERI capabilities. The pointer-to-member
call uses ptrtoint to extract the index, due to this missing fold we can't
infer the actual value loaded from the vtable.
This is the initial constant folding change for this pattern, I will add
InstSimplify/InstCombine folds as a follow-up.
We could fold all ptrtoint(inbounds GEP) to zero here since that is the
only valid offset for an inbounds GEP. If the offset is not zero, that GEP
is poison so returning 0 is valid (https://alive2.llvm.org/ce/z/Gzb5iH).
However, Clang currently generates inbounds GEPs on NULL for hand-written
offsetof() expressions, so this could result in miscompilation.