[ConstantFolding] Fold ptrtoint(gep i8 null, x) -> x
authorAlex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Tue, 28 Sep 2021 14:32:18 +0000 (15:32 +0100)
committerAlex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Tue, 28 Sep 2021 16:57:36 +0000 (17:57 +0100)
commit9049a1c61e9a0cfa5ba41940f2d14597b9e0c431
tree12dcd63e122e5d262760836ab92865fe0ea0730a
parentfc0051011eece1448e8d7f5a478acde5b57e1887
[ConstantFolding] Fold ptrtoint(gep i8 null, x) -> x

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, and 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
an InstCombine fold as a follow-up.

We could fold all inbounds GEP to null (and therefore the ptrtoint to
zero) since zero is the only valid offset for an inbounds GEP. If the
offset is not zero, that GEP is poison and therefore 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 lead to miscompilations.

Reviewed By: lebedev.ri

Differential Revision: https://reviews.llvm.org/D110245
llvm/lib/Analysis/ConstantFolding.cpp
llvm/test/Transforms/InstCombine/ptrtoint-nullgep.ll