aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2025-08-21 16:36:25 +0100
committerGitHub <noreply@github.com>2025-08-21 16:36:25 +0100
commit1b0b59ae4343500d52593c7bd3bce550b3880f7d (patch)
tree120bedec8e600dce90b00baaf121c9eede076686 /llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
parent0594bad039e173673397e528f69bd2c659b33176 (diff)
downloadllvm-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.cpp13
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;