diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 9ca3459a3dfd2..4177f64c6abe2 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2327,175 +2327,6 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (GEPType->isVectorTy()) return nullptr; - // Handle gep(bitcast x) and gep(gep x, 0, 0, 0). - Value *StrippedPtr = PtrOp->stripPointerCasts(); - PointerType *StrippedPtrTy = cast(StrippedPtr->getType()); - - // TODO: The basic approach of these folds is not compatible with opaque - // pointers, because we can't use bitcasts as a hint for a desirable GEP - // type. Instead, we should perform canonicalization directly on the GEP - // type. For now, skip these. - if (StrippedPtr != PtrOp && !StrippedPtrTy->isOpaque()) { - bool HasZeroPointerIndex = false; - Type *StrippedPtrEltTy = StrippedPtrTy->getNonOpaquePointerElementType(); - - if (auto *C = dyn_cast(GEP.getOperand(1))) - HasZeroPointerIndex = C->isZero(); - - // Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... - // into : GEP [10 x i8]* X, i32 0, ... - // - // Likewise, transform: GEP (bitcast i8* X to [0 x i8]*), i32 0, ... - // into : GEP i8* X, ... - // - // This occurs when the program declares an array extern like "int X[];" - if (HasZeroPointerIndex) { - if (auto *CATy = dyn_cast(GEPEltType)) { - // GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ? - if (CATy->getElementType() == StrippedPtrEltTy) { - // -> GEP i8* X, ... - SmallVector Idx(drop_begin(GEP.indices())); - GetElementPtrInst *Res = GetElementPtrInst::Create( - StrippedPtrEltTy, StrippedPtr, Idx, GEP.getName()); - Res->setIsInBounds(GEP.isInBounds()); - if (StrippedPtrTy->getAddressSpace() == GEP.getAddressSpace()) - return Res; - // Insert Res, and create an addrspacecast. - // e.g., - // GEP (addrspacecast i8 addrspace(1)* X to [0 x i8]*), i32 0, ... - // -> - // %0 = GEP i8 addrspace(1)* X, ... - // addrspacecast i8 addrspace(1)* %0 to i8* - return new AddrSpaceCastInst(Builder.Insert(Res), GEPType); - } - - if (auto *XATy = dyn_cast(StrippedPtrEltTy)) { - // GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ? - if (CATy->getElementType() == XATy->getElementType()) { - // -> GEP [10 x i8]* X, i32 0, ... - // At this point, we know that the cast source type is a pointer - // to an array of the same type as the destination pointer - // array. Because the array type is never stepped over (there - // is a leading zero) we can fold the cast into this GEP. - if (StrippedPtrTy->getAddressSpace() == GEP.getAddressSpace()) { - GEP.setSourceElementType(XATy); - return replaceOperand(GEP, 0, StrippedPtr); - } - // Cannot replace the base pointer directly because StrippedPtr's - // address space is different. Instead, create a new GEP followed by - // an addrspacecast. - // e.g., - // GEP (addrspacecast [10 x i8] addrspace(1)* X to [0 x i8]*), - // i32 0, ... - // -> - // %0 = GEP [10 x i8] addrspace(1)* X, ... - // addrspacecast i8 addrspace(1)* %0 to i8* - SmallVector Idx(GEP.indices()); - Value *NewGEP = - Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, Idx, - GEP.getName(), GEP.isInBounds()); - return new AddrSpaceCastInst(NewGEP, GEPType); - } - } - } - } else if (GEP.getNumOperands() == 2 && !IsGEPSrcEleScalable) { - // Skip if GEP source element type is scalable. The type alloc size is - // unknown at compile-time. - // Transform things like: %t = getelementptr i32* - // bitcast ([2 x i32]* %str to i32*), i32 %V into: %t1 = getelementptr [2 - // x i32]* %str, i32 0, i32 %V; bitcast - if (StrippedPtrEltTy->isArrayTy() && - DL.getTypeAllocSize(StrippedPtrEltTy->getArrayElementType()) == - DL.getTypeAllocSize(GEPEltType)) { - Type *IdxType = DL.getIndexType(GEPType); - Value *Idx[2] = {Constant::getNullValue(IdxType), GEP.getOperand(1)}; - Value *NewGEP = Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, Idx, - GEP.getName(), GEP.isInBounds()); - - // V and GEP are both pointer types --> BitCast - return CastInst::CreatePointerBitCastOrAddrSpaceCast(NewGEP, GEPType); - } - - // Transform things like: - // %V = mul i64 %N, 4 - // %t = getelementptr i8* bitcast (i32* %arr to i8*), i32 %V - // into: %t1 = getelementptr i32* %arr, i32 %N; bitcast - if (GEPEltType->isSized() && StrippedPtrEltTy->isSized()) { - // Check that changing the type amounts to dividing the index by a scale - // factor. - uint64_t ResSize = DL.getTypeAllocSize(GEPEltType).getFixedValue(); - uint64_t SrcSize = - DL.getTypeAllocSize(StrippedPtrEltTy).getFixedValue(); - if (ResSize && SrcSize % ResSize == 0) { - Value *Idx = GEP.getOperand(1); - unsigned BitWidth = Idx->getType()->getPrimitiveSizeInBits(); - uint64_t Scale = SrcSize / ResSize; - - // Earlier transforms ensure that the index has the right type - // according to Data Layout, which considerably simplifies the - // logic by eliminating implicit casts. - assert(Idx->getType() == DL.getIndexType(GEPType) && - "Index type does not match the Data Layout preferences"); - - bool NSW; - if (Value *NewIdx = Descale(Idx, APInt(BitWidth, Scale), NSW)) { - // Successfully decomposed Idx as NewIdx * Scale, form a new GEP. - // If the multiplication NewIdx * Scale may overflow then the new - // GEP may not be "inbounds". - Value *NewGEP = - Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, NewIdx, - GEP.getName(), GEP.isInBounds() && NSW); - - // The NewGEP must be pointer typed, so must the old one -> BitCast - return CastInst::CreatePointerBitCastOrAddrSpaceCast(NewGEP, - GEPType); - } - } - } - - // Similarly, transform things like: - // getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp - // (where tmp = 8*tmp2) into: - // getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast - if (GEPEltType->isSized() && StrippedPtrEltTy->isSized() && - StrippedPtrEltTy->isArrayTy()) { - // Check that changing to the array element type amounts to dividing the - // index by a scale factor. - uint64_t ResSize = DL.getTypeAllocSize(GEPEltType).getFixedValue(); - uint64_t ArrayEltSize = - DL.getTypeAllocSize(StrippedPtrEltTy->getArrayElementType()) - .getFixedValue(); - if (ResSize && ArrayEltSize % ResSize == 0) { - Value *Idx = GEP.getOperand(1); - unsigned BitWidth = Idx->getType()->getPrimitiveSizeInBits(); - uint64_t Scale = ArrayEltSize / ResSize; - - // Earlier transforms ensure that the index has the right type - // according to the Data Layout, which considerably simplifies - // the logic by eliminating implicit casts. - assert(Idx->getType() == DL.getIndexType(GEPType) && - "Index type does not match the Data Layout preferences"); - - bool NSW; - if (Value *NewIdx = Descale(Idx, APInt(BitWidth, Scale), NSW)) { - // Successfully decomposed Idx as NewIdx * Scale, form a new GEP. - // If the multiplication NewIdx * Scale may overflow then the new - // GEP may not be "inbounds". - Type *IndTy = DL.getIndexType(GEPType); - Value *Off[2] = {Constant::getNullValue(IndTy), NewIdx}; - - Value *NewGEP = - Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, Off, - GEP.getName(), GEP.isInBounds() && NSW); - // The NewGEP must be pointer typed, so must the old one -> BitCast - return CastInst::CreatePointerBitCastOrAddrSpaceCast(NewGEP, - GEPType); - } - } - } - } - } - if (!GEP.isInBounds()) { unsigned IdxWidth = DL.getIndexSizeInBits(PtrOp->getType()->getPointerAddressSpace());