diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 7f5a7b666903..351fc3b0174f 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2469,31 +2469,43 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) { DL.getIndexSizeInBits(AS)) { uint64_t TyAllocSize = DL.getTypeAllocSize(GEPEltType).getFixedValue(); - bool Matched = false; - uint64_t C; - Value *V = nullptr; if (TyAllocSize == 1) { - V = GEP.getOperand(1); - Matched = true; - } else if (match(GEP.getOperand(1), - m_AShr(m_Value(V), m_ConstantInt(C)))) { - if (TyAllocSize == 1ULL << C) - Matched = true; - } else if (match(GEP.getOperand(1), - m_SDiv(m_Value(V), m_ConstantInt(C)))) { - if (TyAllocSize == C) - Matched = true; + // Canonicalize (gep i8* X, (ptrtoint Y)-(ptrtoint X)) to (bitcast Y), + // but only if the result pointer is only used as if it were an integer, + // or both point to the same underlying object (otherwise provenance is + // not necessarily retained). + Value *X = GEP.getPointerOperand(); + Value *Y; + if (match(GEP.getOperand(1), + m_Sub(m_PtrToInt(m_Value(Y)), m_PtrToInt(m_Specific(X)))) && + GEPType == Y->getType()) { + bool HasSameUnderlyingObject = + getUnderlyingObject(X) == getUnderlyingObject(Y); + bool Changed = false; + GEP.replaceUsesWithIf(Y, [&](Use &U) { + bool ShouldReplace = HasSameUnderlyingObject || + isa<ICmpInst>(U.getUser()) || + isa<PtrToIntInst>(U.getUser()); + Changed |= ShouldReplace; + return ShouldReplace; + }); + return Changed ? &GEP : nullptr; + } + } else { + // Canonicalize (gep T* X, V / sizeof(T)) to (gep i8* X, V) + Value *V; + if ((has_single_bit(TyAllocSize) && + match(GEP.getOperand(1), + m_Exact(m_AShr(m_Value(V), + m_SpecificInt(countr_zero(TyAllocSize)))))) || + match(GEP.getOperand(1), + m_Exact(m_SDiv(m_Value(V), m_SpecificInt(TyAllocSize))))) { + GetElementPtrInst *NewGEP = GetElementPtrInst::Create( + Builder.getInt8Ty(), GEP.getPointerOperand(), V); + NewGEP->setIsInBounds(GEP.isInBounds()); + return NewGEP; + } } - - // Canonicalize (gep i8* X, (ptrtoint Y)-(ptrtoint X)) to (bitcast Y), but - // only if both point to the same underlying object (otherwise provenance - // is not necessarily retained). - Value *Y; - Value *X = GEP.getOperand(0); - if (Matched && - match(V, m_Sub(m_PtrToInt(m_Value(Y)), m_PtrToInt(m_Specific(X)))) && - getUnderlyingObject(X) == getUnderlyingObject(Y)) - return CastInst::CreatePointerBitCastOrAddrSpaceCast(Y, GEPType); } } // We do not handle pointer-vector geps here. |
