@@ -2025,6 +2025,25 @@ Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
2025
2025
return nullptr ;
2026
2026
}
2027
2027
2028
+ // Whether we should convert ptrtoint(gep P, X) to ptrtoint(P) + X
2029
+ static bool shouldPushPtrToIntThroughGEP (GEPOperator *GEP, Type *IntTy,
2030
+ const DataLayout &DL) {
2031
+ if (!GEP->hasOneUse ())
2032
+ return false ;
2033
+
2034
+ // Skip cases whether there is a mismatch between the pointer integer type
2035
+ // and the index type, or the GEP performs an implicit splat operation.
2036
+ if (DL.getIndexType (GEP->getType ()) != IntTy ||
2037
+ GEP->getType () != GEP->getPointerOperand ()->getType ())
2038
+ return false ;
2039
+
2040
+ // (ptrtoint (gep (inttoptr Base), Offset)) -> Base + Offset
2041
+ if (match (GEP->getPointerOperand (), m_OneUse (m_IntToPtr (m_Value ()))))
2042
+ return true ;
2043
+
2044
+ return false ;
2045
+ }
2046
+
2028
2047
Instruction *InstCombinerImpl::visitPtrToInt (PtrToIntInst &CI) {
2029
2048
// If the destination integer type is not the intptr_t type for this target,
2030
2049
// do a ptrtoint to intptr_t then do a trunc or zext. This allows the cast
@@ -2064,10 +2083,8 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
2064
2083
}
2065
2084
2066
2085
// (ptrtoint (gep (inttoptr Base), ...)) -> Base + Offset
2067
- Value *Base;
2068
- if (GEP->hasOneUse () &&
2069
- match (GEP->getPointerOperand (), m_OneUse (m_IntToPtr (m_Value (Base)))) &&
2070
- Base->getType () == Ty) {
2086
+ if (shouldPushPtrToIntThroughGEP (GEP, Ty, DL)) {
2087
+ Value *Base = Builder.CreatePtrToInt (GEP->getPointerOperand (), Ty);
2071
2088
Value *Offset = EmitGEPOffset (GEP);
2072
2089
auto *NewOp = BinaryOperator::CreateAdd (Base, Offset);
2073
2090
if (GEP->hasNoUnsignedWrap () ||
0 commit comments