diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/Local.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/Local.cpp | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/Local.cpp b/contrib/llvm-project/llvm/lib/Analysis/Local.cpp index 5d558de516d3..30757abeb098 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/Local.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/Local.cpp @@ -28,18 +28,18 @@ Value *llvm::emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, // If the GEP is inbounds, we know that none of the addressing operations will // overflow in a signed sense. bool isInBounds = GEPOp->isInBounds() && !NoAssumptions; - - // Build a mask for high order bits. - unsigned IntPtrWidth = IntIdxTy->getScalarType()->getIntegerBitWidth(); - uint64_t PtrSizeMask = - std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth); + auto AddOffset = [&](Value *Offset) { + if (Result) + Result = Builder->CreateAdd(Result, Offset, GEP->getName() + ".offs", + false /*NUW*/, isInBounds /*NSW*/); + else + Result = Offset; + }; gep_type_iterator GTI = gep_type_begin(GEP); for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; ++i, ++GTI) { Value *Op = *i; - uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; - Value *Offset; if (Constant *OpC = dyn_cast<Constant>(Op)) { if (OpC->isZeroValue()) continue; @@ -47,46 +47,34 @@ Value *llvm::emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, // Handle a struct index, which adds its field offset to the pointer. if (StructType *STy = GTI.getStructTypeOrNull()) { uint64_t OpValue = OpC->getUniqueInteger().getZExtValue(); - Size = DL.getStructLayout(STy)->getElementOffset(OpValue); + uint64_t Size = DL.getStructLayout(STy)->getElementOffset(OpValue); if (!Size) continue; - Offset = ConstantInt::get(IntIdxTy, Size); - } else { - // Splat the constant if needed. - if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy()) - OpC = ConstantVector::getSplat( - cast<VectorType>(IntIdxTy)->getElementCount(), OpC); - - Constant *Scale = ConstantInt::get(IntIdxTy, Size); - Constant *OC = - ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/); - Offset = - ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/); - } - } else { - // Splat the index if needed. - if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy()) - Op = Builder->CreateVectorSplat( - cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op); - - // Convert to correct type. - if (Op->getType() != IntIdxTy) - Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName() + ".c"); - if (Size != 1) { - // We'll let instcombine(mul) convert this to a shl if possible. - Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size), - GEP->getName() + ".idx", false /*NUW*/, - isInBounds /*NSW*/); + AddOffset(ConstantInt::get(IntIdxTy, Size)); + continue; } - Offset = Op; } - if (Result) - Result = Builder->CreateAdd(Result, Offset, GEP->getName() + ".offs", - false /*NUW*/, isInBounds /*NSW*/); - else - Result = Offset; + // Splat the index if needed. + if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy()) + Op = Builder->CreateVectorSplat( + cast<VectorType>(IntIdxTy)->getElementCount(), Op); + + // Convert to correct type. + if (Op->getType() != IntIdxTy) + Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName() + ".c"); + TypeSize TSize = DL.getTypeAllocSize(GTI.getIndexedType()); + if (TSize != TypeSize::getFixed(1)) { + Value *Scale = Builder->CreateTypeSize(IntIdxTy->getScalarType(), TSize); + if (IntIdxTy->isVectorTy()) + Scale = Builder->CreateVectorSplat( + cast<VectorType>(IntIdxTy)->getElementCount(), Scale); + // We'll let instcombine(mul) convert this to a shl if possible. + Op = Builder->CreateMul(Op, Scale, GEP->getName() + ".idx", false /*NUW*/, + isInBounds /*NSW*/); + } + AddOffset(Op); } return Result ? Result : Constant::getNullValue(IntIdxTy); } |
