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.  | 
