diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp | 432 |
1 files changed, 216 insertions, 216 deletions
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp index 07e68c4441..2b490d5084 100644 --- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -14,11 +14,11 @@ #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/IR/DIBuilder.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/PatternMatch.h" #include "llvm/Support/KnownBits.h" -#include "llvm/Transforms/InstCombine/InstCombiner.h" +#include "llvm/Transforms/InstCombine/InstCombiner.h" #include <numeric> using namespace llvm; using namespace PatternMatch; @@ -82,8 +82,8 @@ static Value *decomposeSimpleLinearExpr(Value *Val, unsigned &Scale, /// If we find a cast of an allocation instruction, try to eliminate the cast by /// moving the type information into the alloc. -Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI, - AllocaInst &AI) { +Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI, + AllocaInst &AI) { PointerType *PTy = cast<PointerType>(CI.getType()); IRBuilderBase::InsertPointGuard Guard(Builder); @@ -94,18 +94,18 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI, Type *CastElTy = PTy->getElementType(); if (!AllocElTy->isSized() || !CastElTy->isSized()) return nullptr; - // This optimisation does not work for cases where the cast type - // is scalable and the allocated type is not. This because we need to - // know how many times the casted type fits into the allocated type. - // For the opposite case where the allocated type is scalable and the - // cast type is not this leads to poor code quality due to the - // introduction of 'vscale' into the calculations. It seems better to - // bail out for this case too until we've done a proper cost-benefit - // analysis. - bool AllocIsScalable = isa<ScalableVectorType>(AllocElTy); - bool CastIsScalable = isa<ScalableVectorType>(CastElTy); - if (AllocIsScalable != CastIsScalable) return nullptr; - + // This optimisation does not work for cases where the cast type + // is scalable and the allocated type is not. This because we need to + // know how many times the casted type fits into the allocated type. + // For the opposite case where the allocated type is scalable and the + // cast type is not this leads to poor code quality due to the + // introduction of 'vscale' into the calculations. It seems better to + // bail out for this case too until we've done a proper cost-benefit + // analysis. + bool AllocIsScalable = isa<ScalableVectorType>(AllocElTy); + bool CastIsScalable = isa<ScalableVectorType>(CastElTy); + if (AllocIsScalable != CastIsScalable) return nullptr; + Align AllocElTyAlign = DL.getABITypeAlign(AllocElTy); Align CastElTyAlign = DL.getABITypeAlign(CastElTy); if (CastElTyAlign < AllocElTyAlign) return nullptr; @@ -115,15 +115,15 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI, // same, we open the door to infinite loops of various kinds. if (!AI.hasOneUse() && CastElTyAlign == AllocElTyAlign) return nullptr; - // The alloc and cast types should be either both fixed or both scalable. - uint64_t AllocElTySize = DL.getTypeAllocSize(AllocElTy).getKnownMinSize(); - uint64_t CastElTySize = DL.getTypeAllocSize(CastElTy).getKnownMinSize(); + // The alloc and cast types should be either both fixed or both scalable. + uint64_t AllocElTySize = DL.getTypeAllocSize(AllocElTy).getKnownMinSize(); + uint64_t CastElTySize = DL.getTypeAllocSize(CastElTy).getKnownMinSize(); if (CastElTySize == 0 || AllocElTySize == 0) return nullptr; // If the allocation has multiple uses, only promote it if we're not // shrinking the amount of memory being allocated. - uint64_t AllocElTyStoreSize = DL.getTypeStoreSize(AllocElTy).getKnownMinSize(); - uint64_t CastElTyStoreSize = DL.getTypeStoreSize(CastElTy).getKnownMinSize(); + uint64_t AllocElTyStoreSize = DL.getTypeStoreSize(AllocElTy).getKnownMinSize(); + uint64_t CastElTyStoreSize = DL.getTypeStoreSize(CastElTy).getKnownMinSize(); if (!AI.hasOneUse() && CastElTyStoreSize < AllocElTyStoreSize) return nullptr; // See if we can satisfy the modulus by pulling a scale out of the array @@ -138,9 +138,9 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI, if ((AllocElTySize*ArraySizeScale) % CastElTySize != 0 || (AllocElTySize*ArrayOffset ) % CastElTySize != 0) return nullptr; - // We don't currently support arrays of scalable types. - assert(!AllocIsScalable || (ArrayOffset == 1 && ArraySizeScale == 0)); - + // We don't currently support arrays of scalable types. + assert(!AllocIsScalable || (ArrayOffset == 1 && ArraySizeScale == 0)); + unsigned Scale = (AllocElTySize*ArraySizeScale)/CastElTySize; Value *Amt = nullptr; if (Scale == 1) { @@ -177,8 +177,8 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI, /// Given an expression that CanEvaluateTruncated or CanEvaluateSExtd returns /// true for, actually insert the code to evaluate the expression. -Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty, - bool isSigned) { +Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty, + bool isSigned) { if (Constant *C = dyn_cast<Constant>(V)) { C = ConstantExpr::getIntegerCast(C, Ty, isSigned /*Sext or ZExt*/); // If we got a constantexpr back, try to simplify it with DL info. @@ -246,9 +246,9 @@ Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty, return InsertNewInstWith(Res, *I); } -Instruction::CastOps -InstCombinerImpl::isEliminableCastPair(const CastInst *CI1, - const CastInst *CI2) { +Instruction::CastOps +InstCombinerImpl::isEliminableCastPair(const CastInst *CI1, + const CastInst *CI2) { Type *SrcTy = CI1->getSrcTy(); Type *MidTy = CI1->getDestTy(); Type *DstTy = CI2->getDestTy(); @@ -275,7 +275,7 @@ InstCombinerImpl::isEliminableCastPair(const CastInst *CI1, } /// Implement the transforms common to all CastInst visitors. -Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) { +Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) { Value *Src = CI.getOperand(0); // Try to eliminate a cast of a cast. @@ -360,7 +360,7 @@ static bool canNotEvaluateInType(Value *V, Type *Ty) { /// /// This function works on both vectors and scalars. /// -static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC, +static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC, Instruction *CxtI) { if (canAlwaysEvaluateInType(V, Ty)) return true; @@ -477,8 +477,8 @@ static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC, /// trunc (lshr (bitcast <4 x i32> %X to i128), 32) to i32 /// ---> /// extractelement <4 x i32> %X, 1 -static Instruction *foldVecTruncToExtElt(TruncInst &Trunc, - InstCombinerImpl &IC) { +static Instruction *foldVecTruncToExtElt(TruncInst &Trunc, + InstCombinerImpl &IC) { Value *TruncOp = Trunc.getOperand(0); Type *DestType = Trunc.getType(); if (!TruncOp->hasOneUse() || !isa<IntegerType>(DestType)) @@ -515,9 +515,9 @@ static Instruction *foldVecTruncToExtElt(TruncInst &Trunc, return ExtractElementInst::Create(VecInput, IC.Builder.getInt32(Elt)); } -/// Funnel/Rotate left/right may occur in a wider type than necessary because of -/// type promotion rules. Try to narrow the inputs and convert to funnel shift. -Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { +/// Funnel/Rotate left/right may occur in a wider type than necessary because of +/// type promotion rules. Try to narrow the inputs and convert to funnel shift. +Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { assert((isa<VectorType>(Trunc.getSrcTy()) || shouldChangeType(Trunc.getSrcTy(), Trunc.getType())) && "Don't narrow to an illegal scalar type"); @@ -529,43 +529,43 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { if (!isPowerOf2_32(NarrowWidth)) return nullptr; - // First, find an or'd pair of opposite shifts: - // trunc (or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1)) - BinaryOperator *Or0, *Or1; - if (!match(Trunc.getOperand(0), m_OneUse(m_Or(m_BinOp(Or0), m_BinOp(Or1))))) + // First, find an or'd pair of opposite shifts: + // trunc (or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1)) + BinaryOperator *Or0, *Or1; + if (!match(Trunc.getOperand(0), m_OneUse(m_Or(m_BinOp(Or0), m_BinOp(Or1))))) return nullptr; - Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1; - if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0)))) || - !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1)))) || - Or0->getOpcode() == Or1->getOpcode()) + Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1; + if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0)))) || + !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1)))) || + Or0->getOpcode() == Or1->getOpcode()) return nullptr; - // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)). - if (Or0->getOpcode() == BinaryOperator::LShr) { - std::swap(Or0, Or1); - std::swap(ShVal0, ShVal1); - std::swap(ShAmt0, ShAmt1); - } - assert(Or0->getOpcode() == BinaryOperator::Shl && - Or1->getOpcode() == BinaryOperator::LShr && - "Illegal or(shift,shift) pair"); - - // Match the shift amount operands for a funnel/rotate pattern. This always - // matches a subtraction on the R operand. - auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * { + // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)). + if (Or0->getOpcode() == BinaryOperator::LShr) { + std::swap(Or0, Or1); + std::swap(ShVal0, ShVal1); + std::swap(ShAmt0, ShAmt1); + } + assert(Or0->getOpcode() == BinaryOperator::Shl && + Or1->getOpcode() == BinaryOperator::LShr && + "Illegal or(shift,shift) pair"); + + // Match the shift amount operands for a funnel/rotate pattern. This always + // matches a subtraction on the R operand. + 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) + // (shl ShVal0, L) | (lshr ShVal1, Width - L) 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. - if (ShVal0 != ShVal1) - return nullptr; - + // The following patterns currently only work for rotation patterns. + // TODO: Add more general funnel-shift compatible patterns. + if (ShVal0 != ShVal1) + return nullptr; + // The shift amount may be masked with negation: - // (shl ShVal0, (X & (Width - 1))) | (lshr ShVal1, ((-X) & (Width - 1))) + // (shl ShVal0, (X & (Width - 1))) | (lshr ShVal1, ((-X) & (Width - 1))) Value *X; unsigned Mask = Width - 1; if (match(L, m_And(m_Value(X), m_SpecificInt(Mask))) && @@ -581,10 +581,10 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { }; Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, NarrowWidth); - bool IsFshl = true; // Sub on LSHR. + bool IsFshl = true; // Sub on LSHR. if (!ShAmt) { ShAmt = matchShiftAmount(ShAmt1, ShAmt0, NarrowWidth); - IsFshl = false; // Sub on SHL. + IsFshl = false; // Sub on SHL. } if (!ShAmt) return nullptr; @@ -593,28 +593,28 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { // will be a zext, but it could also be the result of an 'and' or 'shift'. unsigned WideWidth = Trunc.getSrcTy()->getScalarSizeInBits(); APInt HiBitMask = APInt::getHighBitsSet(WideWidth, WideWidth - NarrowWidth); - if (!MaskedValueIsZero(ShVal0, HiBitMask, 0, &Trunc) || - !MaskedValueIsZero(ShVal1, HiBitMask, 0, &Trunc)) + if (!MaskedValueIsZero(ShVal0, HiBitMask, 0, &Trunc) || + !MaskedValueIsZero(ShVal1, HiBitMask, 0, &Trunc)) return nullptr; // We have an unnecessarily wide rotate! - // trunc (or (lshr ShVal0, ShAmt), (shl ShVal1, BitWidth - ShAmt)) + // trunc (or (lshr ShVal0, ShAmt), (shl 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); - Value *X, *Y; - X = Y = Builder.CreateTrunc(ShVal0, DestTy); - if (ShVal0 != ShVal1) - Y = Builder.CreateTrunc(ShVal1, DestTy); + Value *X, *Y; + X = Y = Builder.CreateTrunc(ShVal0, DestTy); + if (ShVal0 != ShVal1) + 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 IntrinsicInst::Create(F, {X, Y, NarrowShAmt}); } /// Try to narrow the width of math or bitwise logic instructions by pulling a /// truncate ahead of binary operators. /// TODO: Transforms for truncated shifts should be moved into here. -Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) { +Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) { Type *SrcTy = Trunc.getSrcTy(); Type *DestTy = Trunc.getType(); if (!isa<VectorType>(SrcTy) && !shouldChangeType(SrcTy, DestTy)) @@ -663,7 +663,7 @@ Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) { default: break; } - if (Instruction *NarrowOr = narrowFunnelShift(Trunc)) + if (Instruction *NarrowOr = narrowFunnelShift(Trunc)) return NarrowOr; return nullptr; @@ -719,7 +719,7 @@ static Instruction *shrinkInsertElt(CastInst &Trunc, return nullptr; } -Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { +Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { if (Instruction *Result = commonCastTransforms(Trunc)) return Result; @@ -813,60 +813,60 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { } } - Value *A; - Constant *C; - if (match(Src, m_LShr(m_SExt(m_Value(A)), m_Constant(C)))) { + Value *A; + Constant *C; + if (match(Src, m_LShr(m_SExt(m_Value(A)), m_Constant(C)))) { unsigned AWidth = A->getType()->getScalarSizeInBits(); unsigned MaxShiftAmt = SrcWidth - std::max(DestWidth, AWidth); - auto *OldSh = cast<Instruction>(Src); - bool IsExact = OldSh->isExact(); + auto *OldSh = cast<Instruction>(Src); + bool IsExact = OldSh->isExact(); // If the shift is small enough, all zero bits created by the shift are // removed by the trunc. - if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE, - APInt(SrcWidth, MaxShiftAmt)))) { + if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE, + APInt(SrcWidth, MaxShiftAmt)))) { // trunc (lshr (sext A), C) --> ashr A, C if (A->getType() == DestTy) { - Constant *MaxAmt = ConstantInt::get(SrcTy, DestWidth - 1, false); - Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt); - ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType()); - ShAmt = Constant::mergeUndefsWith(ShAmt, C); - return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt) - : BinaryOperator::CreateAShr(A, ShAmt); + Constant *MaxAmt = ConstantInt::get(SrcTy, DestWidth - 1, false); + Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt); + ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType()); + ShAmt = Constant::mergeUndefsWith(ShAmt, C); + return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt) + : BinaryOperator::CreateAShr(A, ShAmt); } // The types are mismatched, so create a cast after shifting: // trunc (lshr (sext A), C) --> sext/trunc (ashr A, C) if (Src->hasOneUse()) { - Constant *MaxAmt = ConstantInt::get(SrcTy, AWidth - 1, false); - Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt); - ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType()); - Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact); + Constant *MaxAmt = ConstantInt::get(SrcTy, AWidth - 1, false); + Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt); + ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType()); + Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact); return CastInst::CreateIntegerCast(Shift, DestTy, true); } } // TODO: Mask high bits with 'and'. } - // trunc (*shr (trunc A), C) --> trunc(*shr A, C) - if (match(Src, m_OneUse(m_Shr(m_Trunc(m_Value(A)), m_Constant(C))))) { - unsigned MaxShiftAmt = SrcWidth - DestWidth; - - // If the shift is small enough, all zero/sign bits created by the shift are - // removed by the trunc. - if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE, - APInt(SrcWidth, MaxShiftAmt)))) { - auto *OldShift = cast<Instruction>(Src); - bool IsExact = OldShift->isExact(); - auto *ShAmt = ConstantExpr::getIntegerCast(C, A->getType(), true); - ShAmt = Constant::mergeUndefsWith(ShAmt, C); - Value *Shift = - OldShift->getOpcode() == Instruction::AShr - ? Builder.CreateAShr(A, ShAmt, OldShift->getName(), IsExact) - : Builder.CreateLShr(A, ShAmt, OldShift->getName(), IsExact); - return CastInst::CreateTruncOrBitCast(Shift, DestTy); - } - } - + // trunc (*shr (trunc A), C) --> trunc(*shr A, C) + if (match(Src, m_OneUse(m_Shr(m_Trunc(m_Value(A)), m_Constant(C))))) { + unsigned MaxShiftAmt = SrcWidth - DestWidth; + + // If the shift is small enough, all zero/sign bits created by the shift are + // removed by the trunc. + if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE, + APInt(SrcWidth, MaxShiftAmt)))) { + auto *OldShift = cast<Instruction>(Src); + bool IsExact = OldShift->isExact(); + auto *ShAmt = ConstantExpr::getIntegerCast(C, A->getType(), true); + ShAmt = Constant::mergeUndefsWith(ShAmt, C); + Value *Shift = + OldShift->getOpcode() == Instruction::AShr + ? Builder.CreateAShr(A, ShAmt, OldShift->getName(), IsExact) + : Builder.CreateLShr(A, ShAmt, OldShift->getName(), IsExact); + return CastInst::CreateTruncOrBitCast(Shift, DestTy); + } + } + if (Instruction *I = narrowBinOp(Trunc)) return I; @@ -876,19 +876,19 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { if (Instruction *I = shrinkInsertElt(Trunc, Builder)) return I; - if (Src->hasOneUse() && - (isa<VectorType>(SrcTy) || shouldChangeType(SrcTy, DestTy))) { + if (Src->hasOneUse() && + (isa<VectorType>(SrcTy) || shouldChangeType(SrcTy, DestTy))) { // Transform "trunc (shl X, cst)" -> "shl (trunc X), cst" so long as the // dest type is native and cst < dest size. - if (match(Src, m_Shl(m_Value(A), m_Constant(C))) && + if (match(Src, m_Shl(m_Value(A), m_Constant(C))) && !match(A, m_Shr(m_Value(), m_Constant()))) { // Skip shifts of shift by constants. It undoes a combine in // FoldShiftByConstant and is the extend in reg pattern. - APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth); - if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) { + APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth); + if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) { Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr"); - return BinaryOperator::Create(Instruction::Shl, NewTrunc, - ConstantExpr::getTrunc(C, DestTy)); + return BinaryOperator::Create(Instruction::Shl, NewTrunc, + ConstantExpr::getTrunc(C, DestTy)); } } } @@ -905,23 +905,23 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { // ---> // extractelement <8 x i32> (bitcast <4 x i64> %X to <8 x i32>), i32 0 Value *VecOp; - ConstantInt *Cst; + ConstantInt *Cst; if (match(Src, m_OneUse(m_ExtractElt(m_Value(VecOp), m_ConstantInt(Cst))))) { auto *VecOpTy = cast<VectorType>(VecOp->getType()); - auto VecElts = VecOpTy->getElementCount(); + auto VecElts = VecOpTy->getElementCount(); // A badly fit destination size would result in an invalid cast. if (SrcWidth % DestWidth == 0) { uint64_t TruncRatio = SrcWidth / DestWidth; - uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio; + uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio; uint64_t VecOpIdx = Cst->getZExtValue(); uint64_t NewIdx = DL.isBigEndian() ? (VecOpIdx + 1) * TruncRatio - 1 : VecOpIdx * TruncRatio; assert(BitCastNumElts <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits"); - auto *BitCastTo = - VectorType::get(DestTy, BitCastNumElts, VecElts.isScalable()); + auto *BitCastTo = + VectorType::get(DestTy, BitCastNumElts, VecElts.isScalable()); Value *BitCast = Builder.CreateBitCast(VecOp, BitCastTo); return ExtractElementInst::Create(BitCast, Builder.getInt32(NewIdx)); } @@ -930,8 +930,8 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { return nullptr; } -Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext, - bool DoTransform) { +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 // to an integer, then shift the bit to the appropriate place and then // cast to integer to avoid the comparison. @@ -1067,7 +1067,7 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext, /// /// This function works on both vectors and scalars. static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear, - InstCombinerImpl &IC, Instruction *CxtI) { + InstCombinerImpl &IC, Instruction *CxtI) { BitsToClear = 0; if (canAlwaysEvaluateInType(V, Ty)) return true; @@ -1172,7 +1172,7 @@ static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear, } } -Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) { +Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) { // If this zero extend is only used by a truncate, let the truncate be // eliminated before we try to optimize this zext. if (CI.hasOneUse() && isa<TruncInst>(CI.user_back())) @@ -1270,7 +1270,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() && + 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) @@ -1311,8 +1311,8 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) { } /// Transform (sext icmp) to bitwise / integer operations to eliminate the icmp. -Instruction *InstCombinerImpl::transformSExtICmp(ICmpInst *ICI, - Instruction &CI) { +Instruction *InstCombinerImpl::transformSExtICmp(ICmpInst *ICI, + Instruction &CI) { Value *Op0 = ICI->getOperand(0), *Op1 = ICI->getOperand(1); ICmpInst::Predicate Pred = ICI->getPredicate(); @@ -1448,7 +1448,7 @@ static bool canEvaluateSExtd(Value *V, Type *Ty) { return false; } -Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) { +Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) { // If this sign extend is only used by a truncate, let the truncate be // eliminated before we try to optimize this sext. if (CI.hasOneUse() && isa<TruncInst>(CI.user_back())) @@ -1511,28 +1511,28 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) { // for a truncate. If the source and dest are the same type, eliminate the // trunc and extend and just do shifts. For example, turn: // %a = trunc i32 %i to i8 - // %b = shl i8 %a, C - // %c = ashr i8 %b, C + // %b = shl i8 %a, C + // %c = ashr i8 %b, C // %d = sext i8 %c to i32 // into: - // %a = shl i32 %i, 32-(8-C) - // %d = ashr i32 %a, 32-(8-C) + // %a = shl i32 %i, 32-(8-C) + // %d = ashr i32 %a, 32-(8-C) Value *A = nullptr; // TODO: Eventually this could be subsumed by EvaluateInDifferentType. Constant *BA = nullptr, *CA = nullptr; if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A)), m_Constant(BA)), m_Constant(CA))) && - BA->isElementWiseEqual(CA) && A->getType() == DestTy) { - Constant *WideCurrShAmt = ConstantExpr::getSExt(CA, DestTy); - Constant *NumLowbitsLeft = ConstantExpr::getSub( - ConstantInt::get(DestTy, SrcTy->getScalarSizeInBits()), WideCurrShAmt); - Constant *NewShAmt = ConstantExpr::getSub( - ConstantInt::get(DestTy, DestTy->getScalarSizeInBits()), - NumLowbitsLeft); - NewShAmt = - Constant::mergeUndefsWith(Constant::mergeUndefsWith(NewShAmt, BA), CA); - A = Builder.CreateShl(A, NewShAmt, CI.getName()); - return BinaryOperator::CreateAShr(A, NewShAmt); + BA->isElementWiseEqual(CA) && A->getType() == DestTy) { + Constant *WideCurrShAmt = ConstantExpr::getSExt(CA, DestTy); + Constant *NumLowbitsLeft = ConstantExpr::getSub( + ConstantInt::get(DestTy, SrcTy->getScalarSizeInBits()), WideCurrShAmt); + Constant *NewShAmt = ConstantExpr::getSub( + ConstantInt::get(DestTy, DestTy->getScalarSizeInBits()), + NumLowbitsLeft); + NewShAmt = + Constant::mergeUndefsWith(Constant::mergeUndefsWith(NewShAmt, BA), CA); + A = Builder.CreateShl(A, NewShAmt, CI.getName()); + return BinaryOperator::CreateAShr(A, NewShAmt); } return nullptr; @@ -1575,7 +1575,7 @@ static Type *shrinkFPConstantVector(Value *V) { Type *MinType = nullptr; - unsigned NumElts = cast<FixedVectorType>(CVVTy)->getNumElements(); + unsigned NumElts = cast<FixedVectorType>(CVVTy)->getNumElements(); for (unsigned i = 0; i != NumElts; ++i) { auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(i)); if (!CFP) @@ -1656,7 +1656,7 @@ static bool isKnownExactCastIntToFP(CastInst &I) { return false; } -Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) { +Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) { if (Instruction *I = commonCastTransforms(FPT)) return I; @@ -1840,7 +1840,7 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) { return nullptr; } -Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) { +Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) { // If the source operand is a cast from integer to FP and known exact, then // cast the integer operand directly to the destination type. Type *Ty = FPExt.getType(); @@ -1858,7 +1858,7 @@ Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) { /// This is safe if the intermediate type has enough bits in its mantissa to /// accurately represent all values of X. For example, this won't work with /// i64 -> float -> i64. -Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) { +Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) { if (!isa<UIToFPInst>(FI.getOperand(0)) && !isa<SIToFPInst>(FI.getOperand(0))) return nullptr; @@ -1898,29 +1898,29 @@ Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) { return replaceInstUsesWith(FI, X); } -Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) { +Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) { if (Instruction *I = foldItoFPtoI(FI)) return I; return commonCastTransforms(FI); } -Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) { +Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) { if (Instruction *I = foldItoFPtoI(FI)) return I; return commonCastTransforms(FI); } -Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) { +Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) { return commonCastTransforms(CI); } -Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) { +Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) { return commonCastTransforms(CI); } -Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) { +Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) { // If the source integer type is not the intptr_t type for this target, do a // trunc or zext to the intptr_t type, then inttoptr of it. This allows the // cast to be exposed to other transforms. @@ -1943,7 +1943,7 @@ Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) { } /// Implement the transforms for cast of pointer (bitcast/ptrtoint) -Instruction *InstCombinerImpl::commonPointerCastTransforms(CastInst &CI) { +Instruction *InstCombinerImpl::commonPointerCastTransforms(CastInst &CI) { Value *Src = CI.getOperand(0); if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) { @@ -1965,37 +1965,37 @@ Instruction *InstCombinerImpl::commonPointerCastTransforms(CastInst &CI) { return commonCastTransforms(CI); } -Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) { +Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) { // If the destination integer type is not the intptr_t type for this target, // 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(); + Value *SrcOp = CI.getPointerOperand(); 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()); - - Value *P = Builder.CreatePtrToInt(SrcOp, IntPtrTy); - return CastInst::CreateIntegerCast(P, Ty, /*isSigned=*/false); - } - - Value *Vec, *Scalar, *Index; - if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec)), - m_Value(Scalar), m_Value(Index)))) && - Vec->getType() == Ty) { - assert(Vec->getType()->getScalarSizeInBits() == PtrSize && "Wrong type"); - // Convert the scalar to int followed by insert to eliminate one cast: - // p2i (ins (i2p Vec), Scalar, Index --> ins Vec, (p2i Scalar), Index - Value *NewCast = Builder.CreatePtrToInt(Scalar, Ty->getScalarType()); - return InsertElementInst::Create(Vec, NewCast, Index); - } - - return commonPointerCastTransforms(CI); + 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()); + + Value *P = Builder.CreatePtrToInt(SrcOp, IntPtrTy); + return CastInst::CreateIntegerCast(P, Ty, /*isSigned=*/false); + } + + Value *Vec, *Scalar, *Index; + if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec)), + m_Value(Scalar), m_Value(Index)))) && + Vec->getType() == Ty) { + assert(Vec->getType()->getScalarSizeInBits() == PtrSize && "Wrong type"); + // Convert the scalar to int followed by insert to eliminate one cast: + // p2i (ins (i2p Vec), Scalar, Index --> ins Vec, (p2i Scalar), Index + Value *NewCast = Builder.CreatePtrToInt(Scalar, Ty->getScalarType()); + return InsertElementInst::Create(Vec, NewCast, Index); + } + + return commonPointerCastTransforms(CI); } /// This input value (which is known to have vector type) is being zero extended @@ -2014,9 +2014,9 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) { /// Try to replace it with a shuffle (and vector/vector bitcast) if possible. /// /// The source and destination vector types may have different element types. -static Instruction * -optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy, - InstCombinerImpl &IC) { +static Instruction * +optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy, + InstCombinerImpl &IC) { // We can only do this optimization if the output is a multiple of the input // element size, or the input is a multiple of the output element size. // Convert the input type to have the same element type as the output. @@ -2032,14 +2032,14 @@ optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy, return nullptr; SrcTy = - FixedVectorType::get(DestTy->getElementType(), - cast<FixedVectorType>(SrcTy)->getNumElements()); + FixedVectorType::get(DestTy->getElementType(), + cast<FixedVectorType>(SrcTy)->getNumElements()); InVal = IC.Builder.CreateBitCast(InVal, SrcTy); } bool IsBigEndian = IC.getDataLayout().isBigEndian(); - unsigned SrcElts = cast<FixedVectorType>(SrcTy)->getNumElements(); - unsigned DestElts = cast<FixedVectorType>(DestTy)->getNumElements(); + unsigned SrcElts = cast<FixedVectorType>(SrcTy)->getNumElements(); + unsigned DestElts = cast<FixedVectorType>(DestTy)->getNumElements(); assert(SrcElts != DestElts && "Element counts should be different."); @@ -2217,8 +2217,8 @@ static bool collectInsertionElements(Value *V, unsigned Shift, /// /// Into two insertelements that do "buildvector{%inc, %inc5}". static Value *optimizeIntegerToVectorInsertions(BitCastInst &CI, - InstCombinerImpl &IC) { - auto *DestVecTy = cast<FixedVectorType>(CI.getType()); + InstCombinerImpl &IC) { + auto *DestVecTy = cast<FixedVectorType>(CI.getType()); Value *IntInput = CI.getOperand(0); SmallVector<Value*, 8> Elements(DestVecTy->getNumElements()); @@ -2246,7 +2246,7 @@ static Value *optimizeIntegerToVectorInsertions(BitCastInst &CI, /// vectors better than bitcasts of scalars because vector registers are /// usually not type-specific like scalar integer or scalar floating-point. static Instruction *canonicalizeBitCastExtElt(BitCastInst &BitCast, - InstCombinerImpl &IC) { + InstCombinerImpl &IC) { // TODO: Create and use a pattern matcher for ExtractElementInst. auto *ExtElt = dyn_cast<ExtractElementInst>(BitCast.getOperand(0)); if (!ExtElt || !ExtElt->hasOneUse()) @@ -2258,7 +2258,7 @@ static Instruction *canonicalizeBitCastExtElt(BitCastInst &BitCast, if (!VectorType::isValidElementType(DestType)) return nullptr; - auto *NewVecType = VectorType::get(DestType, ExtElt->getVectorOperandType()); + auto *NewVecType = VectorType::get(DestType, ExtElt->getVectorOperandType()); auto *NewBC = IC.Builder.CreateBitCast(ExtElt->getVectorOperand(), NewVecType, "bc"); return ExtractElementInst::Create(NewBC, ExtElt->getIndexOperand()); @@ -2321,10 +2321,10 @@ static Instruction *foldBitCastSelect(BitCastInst &BitCast, // A vector select must maintain the same number of elements in its operands. Type *CondTy = Cond->getType(); Type *DestTy = BitCast.getType(); - if (auto *CondVTy = dyn_cast<VectorType>(CondTy)) - if (!DestTy->isVectorTy() || - CondVTy->getElementCount() != - cast<VectorType>(DestTy)->getElementCount()) + if (auto *CondVTy = dyn_cast<VectorType>(CondTy)) + if (!DestTy->isVectorTy() || + CondVTy->getElementCount() != + cast<VectorType>(DestTy)->getElementCount()) return nullptr; // FIXME: This transform is restricted from changing the select between @@ -2370,8 +2370,8 @@ static bool hasStoreUsersOnly(CastInst &CI) { /// /// All the related PHI nodes can be replaced by new PHI nodes with type A. /// The uses of \p CI can be changed to the new PHI node corresponding to \p PN. -Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, - PHINode *PN) { +Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, + PHINode *PN) { // BitCast used by Store can be handled in InstCombineLoadStoreAlloca.cpp. if (hasStoreUsersOnly(CI)) return nullptr; @@ -2501,7 +2501,7 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, Instruction *RetVal = nullptr; for (auto *OldPN : OldPhiNodes) { PHINode *NewPN = NewPNodes[OldPN]; - for (User *V : make_early_inc_range(OldPN->users())) { + for (User *V : make_early_inc_range(OldPN->users())) { if (auto *SI = dyn_cast<StoreInst>(V)) { assert(SI->isSimple() && SI->getOperand(0) == OldPN); Builder.SetInsertPoint(SI); @@ -2521,7 +2521,7 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, if (BCI == &CI) RetVal = I; } else if (auto *PHI = dyn_cast<PHINode>(V)) { - assert(OldPhiNodes.contains(PHI)); + assert(OldPhiNodes.contains(PHI)); (void) PHI; } else { llvm_unreachable("all uses should be handled"); @@ -2532,7 +2532,7 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, return RetVal; } -Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { +Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { // If the operands are integer typed then apply the integer transforms, // otherwise just apply the common ones. Value *Src = CI.getOperand(0); @@ -2656,11 +2656,11 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { // a bitcast to a vector with the same # elts. Value *ShufOp0 = Shuf->getOperand(0); Value *ShufOp1 = Shuf->getOperand(1); - auto ShufElts = cast<VectorType>(Shuf->getType())->getElementCount(); - auto SrcVecElts = cast<VectorType>(ShufOp0->getType())->getElementCount(); + auto ShufElts = cast<VectorType>(Shuf->getType())->getElementCount(); + auto SrcVecElts = cast<VectorType>(ShufOp0->getType())->getElementCount(); if (Shuf->hasOneUse() && DestTy->isVectorTy() && - cast<VectorType>(DestTy)->getElementCount() == ShufElts && - ShufElts == SrcVecElts) { + cast<VectorType>(DestTy)->getElementCount() == ShufElts && + ShufElts == SrcVecElts) { BitCastInst *Tmp; // If either of the operands is a cast from CI.getType(), then // evaluating the shuffle in the casted destination's type will allow @@ -2683,9 +2683,9 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { // TODO: We should match the related pattern for bitreverse. if (DestTy->isIntegerTy() && DL.isLegalInteger(DestTy->getScalarSizeInBits()) && - SrcTy->getScalarSizeInBits() == 8 && - ShufElts.getKnownMinValue() % 2 == 0 && Shuf->hasOneUse() && - Shuf->isReverse()) { + SrcTy->getScalarSizeInBits() == 8 && + ShufElts.getKnownMinValue() % 2 == 0 && Shuf->hasOneUse() && + Shuf->isReverse()) { assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask"); assert(isa<UndefValue>(ShufOp1) && "Unexpected shuffle op"); Function *Bswap = @@ -2714,7 +2714,7 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { return commonCastTransforms(CI); } -Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) { +Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) { // If the destination pointer element type is not the same as the source's // first do a bitcast to the destination type, and then the addrspacecast. // This allows the cast to be exposed to other transforms. @@ -2725,9 +2725,9 @@ Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) { Type *DestElemTy = DestTy->getElementType(); if (SrcTy->getElementType() != DestElemTy) { Type *MidTy = PointerType::get(DestElemTy, SrcTy->getAddressSpace()); - // Handle vectors of pointers. - if (VectorType *VT = dyn_cast<VectorType>(CI.getType())) - MidTy = VectorType::get(MidTy, VT->getElementCount()); + // Handle vectors of pointers. + if (VectorType *VT = dyn_cast<VectorType>(CI.getType())) + MidTy = VectorType::get(MidTy, VT->getElementCount()); Value *NewBitCast = Builder.CreateBitCast(Src, MidTy); return new AddrSpaceCastInst(NewBitCast, CI.getType()); |