diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
| commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
| tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | |
| parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 278 |
1 files changed, 183 insertions, 95 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 0b53007bb6dc..04877bec94ec 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -277,13 +277,13 @@ InstCombinerImpl::isEliminableCastPair(const CastInst *CI1, /// Implement the transforms common to all CastInst visitors. Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) { Value *Src = CI.getOperand(0); + Type *Ty = CI.getType(); // Try to eliminate a cast of a cast. if (auto *CSrc = dyn_cast<CastInst>(Src)) { // A->B->C cast if (Instruction::CastOps NewOpc = isEliminableCastPair(CSrc, &CI)) { // The first cast (CSrc) is eliminable so we need to fix up or replace // the second cast (CI). CSrc will then have a good chance of being dead. - auto *Ty = CI.getType(); auto *Res = CastInst::Create(NewOpc, CSrc->getOperand(0), Ty); // Point debug users of the dying cast to the new one. if (CSrc->hasOneUse()) @@ -319,6 +319,24 @@ Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) { return NV; } + // Canonicalize a unary shuffle after the cast if neither operation changes + // the size or element size of the input vector. + // TODO: We could allow size-changing ops if that doesn't harm codegen. + // cast (shuffle X, Mask) --> shuffle (cast X), Mask + Value *X; + ArrayRef<int> Mask; + if (match(Src, m_OneUse(m_Shuffle(m_Value(X), m_Undef(), m_Mask(Mask))))) { + // TODO: Allow scalable vectors? + auto *SrcTy = dyn_cast<FixedVectorType>(X->getType()); + auto *DestTy = dyn_cast<FixedVectorType>(Ty); + if (SrcTy && DestTy && + SrcTy->getNumElements() == DestTy->getNumElements() && + SrcTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) { + Value *CastX = Builder.CreateCast(CI.getOpcode(), X, DestTy); + return new ShuffleVectorInst(CastX, UndefValue::get(DestTy), Mask); + } + } + return nullptr; } @@ -526,6 +544,7 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { // even with non-power-of-2 sizes, but it is not a likely scenario. Type *DestTy = Trunc.getType(); unsigned NarrowWidth = DestTy->getScalarSizeInBits(); + unsigned WideWidth = Trunc.getSrcTy()->getScalarSizeInBits(); if (!isPowerOf2_32(NarrowWidth)) return nullptr; @@ -556,8 +575,13 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * { // The shift amounts may add up to the narrow bit width: // (shl ShVal0, L) | (lshr ShVal1, Width - L) - if (match(R, m_OneUse(m_Sub(m_SpecificInt(Width), m_Specific(L))))) - return L; + // If this is a funnel shift (different operands are shifted), then the + // shift amount can not over-shift (create poison) in the narrow type. + unsigned MaxShiftAmountWidth = Log2_32(NarrowWidth); + APInt HiBitMask = ~APInt::getLowBitsSet(WideWidth, MaxShiftAmountWidth); + if (ShVal0 == ShVal1 || MaskedValueIsZero(L, HiBitMask)) + if (match(R, m_OneUse(m_Sub(m_SpecificInt(Width), m_Specific(L))))) + return L; // The following patterns currently only work for rotation patterns. // TODO: Add more general funnel-shift compatible patterns. @@ -589,16 +613,15 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { if (!ShAmt) return nullptr; - // The shifted value must have high zeros in the wide type. Typically, this - // will be a zext, but it could also be the result of an 'and' or 'shift'. - unsigned WideWidth = Trunc.getSrcTy()->getScalarSizeInBits(); + // The right-shifted value must have high zeros in the wide type (for example + // from 'zext', 'and' or 'shift'). High bits of the left-shifted value are + // truncated, so those do not matter. APInt HiBitMask = APInt::getHighBitsSet(WideWidth, WideWidth - NarrowWidth); - if (!MaskedValueIsZero(ShVal0, HiBitMask, 0, &Trunc) || - !MaskedValueIsZero(ShVal1, HiBitMask, 0, &Trunc)) + if (!MaskedValueIsZero(ShVal1, HiBitMask, 0, &Trunc)) return nullptr; // We have an unnecessarily wide rotate! - // trunc (or (lshr ShVal0, ShAmt), (shl ShVal1, BitWidth - ShAmt)) + // trunc (or (shl ShVal0, ShAmt), (lshr ShVal1, BitWidth - ShAmt)) // Narrow the inputs and convert to funnel shift intrinsic: // llvm.fshl.i8(trunc(ShVal), trunc(ShVal), trunc(ShAmt)) Value *NarrowShAmt = Builder.CreateTrunc(ShAmt, DestTy); @@ -608,7 +631,7 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { Y = Builder.CreateTrunc(ShVal1, DestTy); Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr; Function *F = Intrinsic::getDeclaration(Trunc.getModule(), IID, DestTy); - return IntrinsicInst::Create(F, {X, Y, NarrowShAmt}); + return CallInst::Create(F, {X, Y, NarrowShAmt}); } /// Try to narrow the width of math or bitwise logic instructions by pulling a @@ -675,7 +698,7 @@ Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) { static Instruction *shrinkSplatShuffle(TruncInst &Trunc, InstCombiner::BuilderTy &Builder) { auto *Shuf = dyn_cast<ShuffleVectorInst>(Trunc.getOperand(0)); - if (Shuf && Shuf->hasOneUse() && isa<UndefValue>(Shuf->getOperand(1)) && + if (Shuf && Shuf->hasOneUse() && match(Shuf->getOperand(1), m_Undef()) && is_splat(Shuf->getShuffleMask()) && Shuf->getType() == Shuf->getOperand(0)->getType()) { // trunc (shuf X, Undef, SplatMask) --> shuf (trunc X), Undef, SplatMask @@ -708,7 +731,7 @@ static Instruction *shrinkInsertElt(CastInst &Trunc, Value *ScalarOp = InsElt->getOperand(1); Value *Index = InsElt->getOperand(2); - if (isa<UndefValue>(VecOp)) { + if (match(VecOp, m_Undef())) { // trunc (inselt undef, X, Index) --> inselt undef, (trunc X), Index // fptrunc (inselt undef, X, Index) --> inselt undef, (fptrunc X), Index UndefValue *NarrowUndef = UndefValue::get(DestTy); @@ -813,7 +836,7 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { } } - Value *A; + Value *A, *B; Constant *C; if (match(Src, m_LShr(m_SExt(m_Value(A)), m_Constant(C)))) { unsigned AWidth = A->getType()->getScalarSizeInBits(); @@ -927,9 +950,23 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { } } + // trunc (ctlz_i32(zext(A), B) --> add(ctlz_i16(A, B), C) + if (match(Src, m_OneUse(m_Intrinsic<Intrinsic::ctlz>(m_ZExt(m_Value(A)), + m_Value(B))))) { + unsigned AWidth = A->getType()->getScalarSizeInBits(); + if (AWidth == DestWidth && AWidth > Log2_32(SrcWidth)) { + Value *WidthDiff = ConstantInt::get(A->getType(), SrcWidth - AWidth); + Value *NarrowCtlz = + Builder.CreateIntrinsic(Intrinsic::ctlz, {Trunc.getType()}, {A, B}); + return BinaryOperator::CreateAdd(NarrowCtlz, WidthDiff); + } + } return nullptr; } +/// Transform (zext icmp) to bitwise / integer operations in order to +/// eliminate it. If DoTransform is false, just test whether the given +/// (zext icmp) can be transformed. Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext, bool DoTransform) { // If we are just checking for a icmp eq of a single bit and zext'ing it @@ -1008,10 +1045,27 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext, } } - // icmp ne A, B is equal to xor A, B when A and B only really have one bit. - // It is also profitable to transform icmp eq into not(xor(A, B)) because that - // may lead to additional simplifications. if (Cmp->isEquality() && Zext.getType() == Cmp->getOperand(0)->getType()) { + // Test if a bit is clear/set using a shifted-one mask: + // zext (icmp eq (and X, (1 << ShAmt)), 0) --> and (lshr (not X), ShAmt), 1 + // zext (icmp ne (and X, (1 << ShAmt)), 0) --> and (lshr X, ShAmt), 1 + Value *X, *ShAmt; + if (Cmp->hasOneUse() && match(Cmp->getOperand(1), m_ZeroInt()) && + match(Cmp->getOperand(0), + m_OneUse(m_c_And(m_Shl(m_One(), m_Value(ShAmt)), m_Value(X))))) { + if (!DoTransform) + return Cmp; + + if (Cmp->getPredicate() == ICmpInst::ICMP_EQ) + X = Builder.CreateNot(X); + Value *Lshr = Builder.CreateLShr(X, ShAmt); + Value *And1 = Builder.CreateAnd(Lshr, ConstantInt::get(X->getType(), 1)); + return replaceInstUsesWith(Zext, And1); + } + + // icmp ne A, B is equal to xor A, B when A and B only really have one bit. + // It is also profitable to transform icmp eq into not(xor(A, B)) because + // that may lead to additional simplifications. if (IntegerType *ITy = dyn_cast<IntegerType>(Zext.getType())) { Value *LHS = Cmp->getOperand(0); Value *RHS = Cmp->getOperand(1); @@ -1270,6 +1324,7 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) { ICmpInst *LHS = dyn_cast<ICmpInst>(SrcI->getOperand(0)); ICmpInst *RHS = dyn_cast<ICmpInst>(SrcI->getOperand(1)); if (LHS && RHS && LHS->hasOneUse() && RHS->hasOneUse() && + LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType() && (transformZExtICmp(LHS, CI, false) || transformZExtICmp(RHS, CI, false))) { // zext (or icmp, icmp) -> or (zext icmp), (zext icmp) @@ -1458,6 +1513,8 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) { Value *Src = CI.getOperand(0); Type *SrcTy = Src->getType(), *DestTy = CI.getType(); + unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); + unsigned DestBitSize = DestTy->getScalarSizeInBits(); // If we know that the value being extended is positive, we can use a zext // instead. @@ -1475,9 +1532,6 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) { Value *Res = EvaluateInDifferentType(Src, DestTy, true); assert(Res->getType() == DestTy); - uint32_t SrcBitSize = SrcTy->getScalarSizeInBits(); - uint32_t DestBitSize = DestTy->getScalarSizeInBits(); - // If the high bits are already filled with sign bit, just replace this // cast with the result. if (ComputeNumSignBits(Res, 0, &CI) > DestBitSize - SrcBitSize) @@ -1489,15 +1543,32 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) { ShAmt); } - // If the input is a trunc from the destination type, then turn sext(trunc(x)) - // into shifts. Value *X; - if (match(Src, m_OneUse(m_Trunc(m_Value(X)))) && X->getType() == DestTy) { - // sext(trunc(X)) --> ashr(shl(X, C), C) - unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); - unsigned DestBitSize = DestTy->getScalarSizeInBits(); - Constant *ShAmt = ConstantInt::get(DestTy, DestBitSize - SrcBitSize); - return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShAmt), ShAmt); + if (match(Src, m_Trunc(m_Value(X)))) { + // If the input has more sign bits than bits truncated, then convert + // directly to final type. + unsigned XBitSize = X->getType()->getScalarSizeInBits(); + if (ComputeNumSignBits(X, 0, &CI) > XBitSize - SrcBitSize) + return CastInst::CreateIntegerCast(X, DestTy, /* isSigned */ true); + + // If input is a trunc from the destination type, then convert into shifts. + if (Src->hasOneUse() && X->getType() == DestTy) { + // sext (trunc X) --> ashr (shl X, C), C + Constant *ShAmt = ConstantInt::get(DestTy, DestBitSize - SrcBitSize); + return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShAmt), ShAmt); + } + + // If we are replacing shifted-in high zero bits with sign bits, convert + // the logic shift to arithmetic shift and eliminate the cast to + // intermediate type: + // sext (trunc (lshr Y, C)) --> sext/trunc (ashr Y, C) + Value *Y; + if (Src->hasOneUse() && + match(X, m_LShr(m_Value(Y), + m_SpecificIntAllowUndef(XBitSize - SrcBitSize)))) { + Value *Ashr = Builder.CreateAShr(Y, XBitSize - SrcBitSize); + return CastInst::CreateIntegerCast(Ashr, DestTy, /* isSigned */ true); + } } if (ICmpInst *ICI = dyn_cast<ICmpInst>(Src)) @@ -1568,13 +1639,16 @@ static Type *shrinkFPConstant(ConstantFP *CFP) { // TODO: Make these support undef elements. static Type *shrinkFPConstantVector(Value *V) { auto *CV = dyn_cast<Constant>(V); - auto *CVVTy = dyn_cast<VectorType>(V->getType()); + auto *CVVTy = dyn_cast<FixedVectorType>(V->getType()); if (!CV || !CVVTy) return nullptr; Type *MinType = nullptr; - unsigned NumElts = cast<FixedVectorType>(CVVTy)->getNumElements(); + unsigned NumElts = CVVTy->getNumElements(); + + // For fixed-width vectors we find the minimal type by looking + // through the constant values of the vector. for (unsigned i = 0; i != NumElts; ++i) { auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(i)); if (!CFP) @@ -1606,7 +1680,15 @@ static Type *getMinimumFPType(Value *V) { if (Type *T = shrinkFPConstant(CFP)) return T; - // Try to shrink a vector of FP constants. + // We can only correctly find a minimum type for a scalable vector when it is + // a splat. For splats of constant values the fpext is wrapped up as a + // ConstantExpr. + if (auto *FPCExt = dyn_cast<ConstantExpr>(V)) + if (FPCExt->getOpcode() == Instruction::FPExt) + return FPCExt->getOperand(0)->getType(); + + // Try to shrink a vector of FP constants. This returns nullptr on scalable + // vectors if (Type *T = shrinkFPConstantVector(V)) return T; @@ -1926,11 +2008,8 @@ Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) { unsigned AS = CI.getAddressSpace(); if (CI.getOperand(0)->getType()->getScalarSizeInBits() != DL.getPointerSizeInBits(AS)) { - Type *Ty = DL.getIntPtrType(CI.getContext(), AS); - // Handle vectors of pointers. - if (auto *CIVTy = dyn_cast<VectorType>(CI.getType())) - Ty = VectorType::get(Ty, CIVTy->getElementCount()); - + Type *Ty = CI.getOperand(0)->getType()->getWithNewType( + DL.getIntPtrType(CI.getContext(), AS)); Value *P = Builder.CreateZExtOrTrunc(CI.getOperand(0), Ty); return new IntToPtrInst(P, CI.getType()); } @@ -1969,16 +2048,14 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) { // do a ptrtoint to intptr_t then do a trunc or zext. This allows the cast // to be exposed to other transforms. Value *SrcOp = CI.getPointerOperand(); + Type *SrcTy = SrcOp->getType(); Type *Ty = CI.getType(); unsigned AS = CI.getPointerAddressSpace(); unsigned TySize = Ty->getScalarSizeInBits(); unsigned PtrSize = DL.getPointerSizeInBits(AS); if (TySize != PtrSize) { - Type *IntPtrTy = DL.getIntPtrType(CI.getContext(), AS); - // Handle vectors of pointers. - if (auto *VecTy = dyn_cast<VectorType>(Ty)) - IntPtrTy = VectorType::get(IntPtrTy, VecTy->getElementCount()); - + Type *IntPtrTy = + SrcTy->getWithNewType(DL.getIntPtrType(CI.getContext(), AS)); Value *P = Builder.CreatePtrToInt(SrcOp, IntPtrTy); return CastInst::CreateIntegerCast(P, Ty, /*isSigned=*/false); } @@ -2402,6 +2479,12 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, Value *Addr = LI->getOperand(0); if (Addr == &CI || isa<LoadInst>(Addr)) return nullptr; + // Don't tranform "load <256 x i32>, <256 x i32>*" to + // "load x86_amx, x86_amx*", because x86_amx* is invalid. + // TODO: Remove this check when bitcast between vector and x86_amx + // is replaced with a specific intrinsic. + if (DestTy->isX86_AMXTy()) + return nullptr; if (LI->hasOneUse() && LI->isSimple()) continue; // If a LoadInst has more than one use, changing the type of loaded @@ -2476,7 +2559,7 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, NewV = combineLoadToNewType(*LI, DestTy); // Remove the old load and its use in the old phi, which itself becomes // dead once the whole transform finishes. - replaceInstUsesWith(*LI, UndefValue::get(LI->getType())); + replaceInstUsesWith(*LI, PoisonValue::get(LI->getType())); eraseInstFromFunction(*LI); } else if (auto *BCI = dyn_cast<BitCastInst>(V)) { NewV = BCI->getOperand(0); @@ -2531,6 +2614,57 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, return RetVal; } +static Instruction *convertBitCastToGEP(BitCastInst &CI, IRBuilderBase &Builder, + const DataLayout &DL) { + Value *Src = CI.getOperand(0); + PointerType *SrcPTy = cast<PointerType>(Src->getType()); + PointerType *DstPTy = cast<PointerType>(CI.getType()); + + // Bitcasts involving opaque pointers cannot be converted into a GEP. + if (SrcPTy->isOpaque() || DstPTy->isOpaque()) + return nullptr; + + Type *DstElTy = DstPTy->getElementType(); + Type *SrcElTy = SrcPTy->getElementType(); + + // When the type pointed to is not sized the cast cannot be + // turned into a gep. + if (!SrcElTy->isSized()) + return nullptr; + + // If the source and destination are pointers, and this cast is equivalent + // to a getelementptr X, 0, 0, 0... turn it into the appropriate gep. + // This can enhance SROA and other transforms that want type-safe pointers. + unsigned NumZeros = 0; + while (SrcElTy && SrcElTy != DstElTy) { + SrcElTy = GetElementPtrInst::getTypeAtIndex(SrcElTy, (uint64_t)0); + ++NumZeros; + } + + // If we found a path from the src to dest, create the getelementptr now. + if (SrcElTy == DstElTy) { + SmallVector<Value *, 8> Idxs(NumZeros + 1, Builder.getInt32(0)); + GetElementPtrInst *GEP = + GetElementPtrInst::Create(SrcPTy->getElementType(), Src, Idxs); + + // If the source pointer is dereferenceable, then assume it points to an + // allocated object and apply "inbounds" to the GEP. + bool CanBeNull, CanBeFreed; + if (Src->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed)) { + // In a non-default address space (not 0), a null pointer can not be + // assumed inbounds, so ignore that case (dereferenceable_or_null). + // The reason is that 'null' is not treated differently in these address + // spaces, and we consequently ignore the 'gep inbounds' special case + // for 'null' which allows 'inbounds' on 'null' if the indices are + // zeros. + if (SrcPTy->getAddressSpace() == 0 || !CanBeNull) + GEP->setIsInBounds(); + } + return GEP; + } + return nullptr; +} + Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { // If the operands are integer typed then apply the integer transforms, // otherwise just apply the common ones. @@ -2544,17 +2678,6 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { return replaceInstUsesWith(CI, Src); if (isa<PointerType>(SrcTy) && isa<PointerType>(DestTy)) { - PointerType *SrcPTy = cast<PointerType>(SrcTy); - PointerType *DstPTy = cast<PointerType>(DestTy); - Type *DstElTy = DstPTy->getElementType(); - Type *SrcElTy = SrcPTy->getElementType(); - - // Casting pointers between the same type, but with different address spaces - // is an addrspace cast rather than a bitcast. - if ((DstElTy == SrcElTy) && - (DstPTy->getAddressSpace() != SrcPTy->getAddressSpace())) - return new AddrSpaceCastInst(Src, DestTy); - // If we are casting a alloca to a pointer to a type of the same // size, rewrite the allocation instruction to allocate the "right" type. // There is no need to modify malloc calls because it is their bitcast that @@ -2563,50 +2686,15 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { if (Instruction *V = PromoteCastOfAllocation(CI, *AI)) return V; - // When the type pointed to is not sized the cast cannot be - // turned into a gep. - Type *PointeeType = - cast<PointerType>(Src->getType()->getScalarType())->getElementType(); - if (!PointeeType->isSized()) - return nullptr; - - // If the source and destination are pointers, and this cast is equivalent - // to a getelementptr X, 0, 0, 0... turn it into the appropriate gep. - // This can enhance SROA and other transforms that want type-safe pointers. - unsigned NumZeros = 0; - while (SrcElTy && SrcElTy != DstElTy) { - SrcElTy = GetElementPtrInst::getTypeAtIndex(SrcElTy, (uint64_t)0); - ++NumZeros; - } - - // If we found a path from the src to dest, create the getelementptr now. - if (SrcElTy == DstElTy) { - SmallVector<Value *, 8> Idxs(NumZeros + 1, Builder.getInt32(0)); - GetElementPtrInst *GEP = - GetElementPtrInst::Create(SrcPTy->getElementType(), Src, Idxs); - - // If the source pointer is dereferenceable, then assume it points to an - // allocated object and apply "inbounds" to the GEP. - bool CanBeNull; - if (Src->getPointerDereferenceableBytes(DL, CanBeNull)) { - // In a non-default address space (not 0), a null pointer can not be - // assumed inbounds, so ignore that case (dereferenceable_or_null). - // The reason is that 'null' is not treated differently in these address - // spaces, and we consequently ignore the 'gep inbounds' special case - // for 'null' which allows 'inbounds' on 'null' if the indices are - // zeros. - if (SrcPTy->getAddressSpace() == 0 || !CanBeNull) - GEP->setIsInBounds(); - } - return GEP; - } + if (Instruction *I = convertBitCastToGEP(CI, Builder, DL)) + return I; } if (FixedVectorType *DestVTy = dyn_cast<FixedVectorType>(DestTy)) { // Beware: messing with this target-specific oddity may cause trouble. if (DestVTy->getNumElements() == 1 && SrcTy->isX86_MMXTy()) { Value *Elem = Builder.CreateBitCast(Src, DestVTy->getElementType()); - return InsertElementInst::Create(UndefValue::get(DestTy), Elem, + return InsertElementInst::Create(PoisonValue::get(DestTy), Elem, Constant::getNullValue(Type::getInt32Ty(CI.getContext()))); } @@ -2686,11 +2774,11 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { ShufElts.getKnownMinValue() % 2 == 0 && Shuf->hasOneUse() && Shuf->isReverse()) { assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask"); - assert(isa<UndefValue>(ShufOp1) && "Unexpected shuffle op"); + assert(match(ShufOp1, m_Undef()) && "Unexpected shuffle op"); Function *Bswap = Intrinsic::getDeclaration(CI.getModule(), Intrinsic::bswap, DestTy); Value *ScalarX = Builder.CreateBitCast(ShufOp0, DestTy); - return IntrinsicInst::Create(Bswap, { ScalarX }); + return CallInst::Create(Bswap, { ScalarX }); } } @@ -2721,9 +2809,9 @@ Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) { PointerType *SrcTy = cast<PointerType>(Src->getType()->getScalarType()); PointerType *DestTy = cast<PointerType>(CI.getType()->getScalarType()); - Type *DestElemTy = DestTy->getElementType(); - if (SrcTy->getElementType() != DestElemTy) { - Type *MidTy = PointerType::get(DestElemTy, SrcTy->getAddressSpace()); + if (!SrcTy->hasSameElementTypeAs(DestTy)) { + Type *MidTy = + PointerType::getWithSamePointeeType(DestTy, SrcTy->getAddressSpace()); // Handle vectors of pointers. if (VectorType *VT = dyn_cast<VectorType>(CI.getType())) MidTy = VectorType::get(MidTy, VT->getElementCount()); |
