diff options
author | Florian Hahn <flo@fhahn.com> | 2025-08-21 16:36:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-21 16:36:25 +0100 |
commit | 1b0b59ae4343500d52593c7bd3bce550b3880f7d (patch) | |
tree | 120bedec8e600dce90b00baaf121c9eede076686 /llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | |
parent | 0594bad039e173673397e528f69bd2c659b33176 (diff) | |
download | llvm-1b0b59ae4343500d52593c7bd3bce550b3880f7d.zip llvm-1b0b59ae4343500d52593c7bd3bce550b3880f7d.tar.gz llvm-1b0b59ae4343500d52593c7bd3bce550b3880f7d.tar.bz2 |
[InstComb] Fold inttoptr (add (ptrtoint %B), %O) -> GEP for ICMP users. (#153421)
Replace inttoptr (add (ptrtoint %B), %O) with (getelementptr i8, %B, %o)
if all users are ICmp instruction, which in turn means only the address
value is compared. We should be able to do this, if the src pointer,
the integer type and the destination pointer types have the same
bitwidth and address space.
A common source of such (inttoptr (add (ptrtoint %B), %O)) is from
various iterations in libc++.
In practice this triggers in a number of files in Clang and various open
source projects, including cppcheck, diamond, llama and more.
Alive2 Proof with constant offset: https://alive2.llvm.org/ce/z/K_5N_B
PR: https://github.com/llvm/llvm-project/pull/153421
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 801ac00..6ef55d4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -2072,6 +2072,19 @@ Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) { return new IntToPtrInst(P, CI.getType()); } + // Replace (inttoptr (add (ptrtoint %Base), %Offset)) with + // (getelementptr i8, %Base, %Offset) if all users are ICmps. + Value *Base; + Value *Offset; + if (match(CI.getOperand(0), + m_OneUse(m_c_Add(m_PtrToIntSameSize(DL, m_Value(Base)), + m_Value(Offset)))) && + CI.getType()->getPointerAddressSpace() == + Base->getType()->getPointerAddressSpace() && + all_of(CI.users(), IsaPred<ICmpInst>)) { + return GetElementPtrInst::Create(Builder.getInt8Ty(), Base, Offset); + } + if (Instruction *I = commonCastTransforms(CI)) return I; |