diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4349,40 +4349,32 @@ // doesn't truncate the pointers. if (Ops[1]->getType()->getScalarSizeInBits() == Q.DL.getPointerSizeInBits(AS)) { - auto PtrToInt = [GEPTy](Value *P) -> Value * { - Value *Temp; - if (match(P, m_PtrToInt(m_Value(Temp)))) - if (Temp->getType() == GEPTy) - return Temp; - return nullptr; - }; - - // FIXME: The following transforms are only legal if P and V have the - // same provenance (PR44403). Check whether getUnderlyingObject() is - // the same? - - // getelementptr V, (sub P, V) -> P if P points to a type of size 1. + // getelementptr V, (sub P, V) -> (bitcast P) if P points to a type of + // size 1. if (TyAllocSize == 1 && - match(Ops[1], m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))))) - if (Value *R = PtrToInt(P)) - return R; + match(Ops[1], m_Sub(m_PtrToInt(m_Value(P)), + m_PtrToInt(m_Specific(Ops[0])))) && + P->getType() == GEPTy && + getUnderlyingObject(P) == getUnderlyingObject(Ops[0])) + return P; - // getelementptr V, (ashr (sub P, V), C) -> Q + // getelementptr V, (ashr (sub P, V), C) -> (bitcast P) // if P points to a type of size 1 << C. - if (match(Ops[1], - m_AShr(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))), - m_ConstantInt(C))) && - TyAllocSize == 1ULL << C) - if (Value *R = PtrToInt(P)) - return R; - - // getelementptr V, (sdiv (sub P, V), C) -> Q + if (match(Ops[1], m_AShr(m_Sub(m_PtrToInt(m_Value(P)), + m_PtrToInt(m_Specific(Ops[0]))), + m_ConstantInt(C))) && + TyAllocSize == 1ULL << C && P->getType() == GEPTy && + getUnderlyingObject(P) == getUnderlyingObject(Ops[0])) + return P; + + // getelementptr V, (sdiv (sub P, V), C) -> (bitcast P) // if P points to a type of size C. - if (match(Ops[1], - m_SDiv(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))), - m_SpecificInt(TyAllocSize)))) - if (Value *R = PtrToInt(P)) - return R; + if (match(Ops[1], m_SDiv(m_Sub(m_PtrToInt(m_Value(P)), + m_PtrToInt(m_Specific(Ops[0]))), + m_SpecificInt(TyAllocSize))) && + P->getType() == GEPTy && + getUnderlyingObject(P) == getUnderlyingObject(Ops[0])) + return P; } } }