From 6de29f8d960505421d61c80cdb738e16720b6c0e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 15 Jun 2009 22:12:54 +0000 Subject: [PATCH] Support vector casts in more places, fixing a variety of assertion failures. To support this, add some utility functions to Type to help support vector/scalar-independent code. Change ConstantInt::get and ConstantFP::get to support vector types, and add an overload to ConstantInt::get that uses a static IntegerType type, for convenience. Introduce a new getConstant method for ScalarEvolution, to simplify common use cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73431 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/ScalarEvolution.h | 1 + include/llvm/Constants.h | 15 +- include/llvm/Type.h | 23 +- lib/Analysis/ConstantFolding.cpp | 4 +- lib/Analysis/ScalarEvolution.cpp | 11 +- lib/Analysis/ScalarEvolutionExpander.cpp | 4 +- lib/Analysis/ValueTracking.cpp | 35 ++- .../Instrumentation/RSProfiling.cpp | 12 +- .../Scalar/InstructionCombining.cpp | 281 ++++++++++-------- lib/Transforms/Scalar/LoopIndexSplit.cpp | 4 +- lib/Transforms/Scalar/LoopStrengthReduce.cpp | 14 +- lib/VMCore/ConstantFold.cpp | 32 +- lib/VMCore/Constants.cpp | 114 +++++-- lib/VMCore/Instructions.cpp | 64 ++-- lib/VMCore/Type.cpp | 30 ++ lib/VMCore/Verifier.cpp | 20 +- test/Feature/vector-cast-constant-exprs.ll | 37 +++ test/Transforms/InstCombine/vector-casts.ll | 55 ++++ 18 files changed, 497 insertions(+), 259 deletions(-) create mode 100644 test/Feature/vector-cast-constant-exprs.ll create mode 100644 test/Transforms/InstCombine/vector-casts.ll diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index aa9789c96a9..88a4a276adf 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -418,6 +418,7 @@ namespace llvm { SCEVHandle getConstant(ConstantInt *V); SCEVHandle getConstant(const APInt& Val); + SCEVHandle getConstant(const Type *Ty, uint64_t V, bool isSigned = false); SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty); SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty); SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty); diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index ed0fe2740f9..75164ff12cc 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -107,14 +107,19 @@ public: /// either getSExtValue() or getZExtValue() will yield a correctly sized and /// signed value for the type Ty. /// @brief Get a ConstantInt for a specific value. - static ConstantInt *get(const Type *Ty, uint64_t V, bool isSigned = false); + static ConstantInt *get(const IntegerType *Ty, + uint64_t V, bool isSigned = false); + static Constant *get(const Type *Ty, uint64_t V, bool isSigned = false); /// Return a ConstantInt with the specified value for the specified type. The /// value V will be canonicalized to a an unsigned APInt. Accessing it with /// either getSExtValue() or getZExtValue() will yield a correctly sized and /// signed value for the type Ty. /// @brief Get a ConstantInt for a specific signed value. - static ConstantInt *getSigned(const Type *Ty, int64_t V) { + static ConstantInt *getSigned(const IntegerType *Ty, int64_t V) { + return get(Ty, V, true); + } + static Constant *getSigned(const Type *Ty, int64_t V) { return get(Ty, V, true); } @@ -122,6 +127,10 @@ public: /// type is the integer type that corresponds to the bit width of the value. static ConstantInt *get(const APInt &V); + /// If Ty is a vector type, return a Constant with a splat of the given + /// value. Otherwise return a ConstantInt for the given value. + static Constant *get(const Type *Ty, const APInt &V); + /// getType - Specialize the getType() method to always return an IntegerType, /// which reduces the amount of casting needed in parts of the compiler. /// @@ -251,7 +260,7 @@ public: /// get() - This returns a constant fp for the specified value in the /// specified type. This should only be used for simple constant values like /// 2.0/1.0 etc, that are known-valid both as double and as the target format. - static ConstantFP *get(const Type *Ty, double V); + static Constant *get(const Type *Ty, double V); /// isValueValidForType - return true if Ty is big enough to represent V. static bool isValueValidForType(const Type *Ty, const APFloat& V); diff --git a/include/llvm/Type.h b/include/llvm/Type.h index c1732af09bd..9a48731ede9 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -268,19 +268,16 @@ public: /// primitive type. /// unsigned getPrimitiveSizeInBits() const; - + + /// getScalarSizeInBits - If this is a vector type, return the + /// getPrimitiveSizeInBits value for the element type. Otherwise return the + /// getPrimitiveSizeInBits value for this type. + unsigned getScalarSizeInBits() const; + /// getFPMantissaWidth - Return the width of the mantissa of this type. This - /// is only valid on scalar floating point types. If the FP type does not + /// is only valid on floating point types. If the FP type does not /// have a stable mantissa (e.g. ppc long double), this method returns -1. - int getFPMantissaWidth() const { - assert(isFloatingPoint() && "Not a floating point type!"); - if (ID == FloatTyID) return 24; - if (ID == DoubleTyID) return 53; - if (ID == X86_FP80TyID) return 64; - if (ID == FP128TyID) return 113; - assert(ID == PPC_FP128TyID && "unknown fp type"); - return -1; - } + int getFPMantissaWidth() const; /// getForwardedType - Return the type that this type has been resolved to if /// it has been resolved to anything. This is used to implement the @@ -296,6 +293,10 @@ public: /// function. const Type *getVAArgsPromotedType() const; + /// getScalarType - If this is a vector type, return the element type, + /// otherwise return this. + const Type *getScalarType() const; + //===--------------------------------------------------------------------===// // Type Iteration support // diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 261c635feb4..5aa4d56c4e6 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -365,7 +365,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, if (ConstantExpr *CE = dyn_cast(Ops[0])) { if (TD && CE->getOpcode() == Instruction::IntToPtr) { Constant *Input = CE->getOperand(0); - unsigned InWidth = Input->getType()->getPrimitiveSizeInBits(); + unsigned InWidth = Input->getType()->getScalarSizeInBits(); if (TD->getPointerSizeInBits() < InWidth) { Constant *Mask = ConstantInt::get(APInt::getLowBitsSet(InWidth, @@ -384,7 +384,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, if (ConstantExpr *CE = dyn_cast(Ops[0])) { if (TD && TD->getPointerSizeInBits() <= - CE->getType()->getPrimitiveSizeInBits()) { + CE->getType()->getScalarSizeInBits()) { if (CE->getOpcode() == Instruction::PtrToInt) { Constant *Input = CE->getOperand(0); Constant *C = FoldBitCast(Input, DestTy, *TD); diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 16dc281ae17..ca805bd8670 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -186,6 +186,11 @@ SCEVHandle ScalarEvolution::getConstant(const APInt& Val) { return getConstant(ConstantInt::get(Val)); } +SCEVHandle +ScalarEvolution::getConstant(const Type *Ty, uint64_t V, bool isSigned) { + return getConstant(ConstantInt::get(cast(Ty), V, isSigned)); +} + const Type *SCEVConstant::getType() const { return V->getType(); } void SCEVConstant::print(raw_ostream &OS) const { @@ -2891,7 +2896,7 @@ ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS, unsigned MaxSteps = MaxBruteForceIterations; for (unsigned IterationNum = 0; IterationNum != MaxSteps; ++IterationNum) { ConstantInt *ItCst = - ConstantInt::get(IdxExpr->getType(), IterationNum); + ConstantInt::get(cast(IdxExpr->getType()), IterationNum); ConstantInt *Val = EvaluateConstantChrecAtConstant(IdxExpr, ItCst, *this); // Form the GEP offset. @@ -3086,7 +3091,7 @@ ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen) if (CondVal->getValue() == uint64_t(ExitWhen)) { ConstantEvolutionLoopExitValue[PN] = PHIVal; ++NumBruteForceTripCountsComputed; - return getConstant(ConstantInt::get(Type::Int32Ty, IterationNum)); + return getConstant(Type::Int32Ty, IterationNum); } // Compute the value of the PHI node for the next iteration. @@ -3777,7 +3782,7 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range, // iteration exits. unsigned BitWidth = SE.getTypeSizeInBits(getType()); if (!Range.contains(APInt(BitWidth, 0))) - return SE.getConstant(ConstantInt::get(getType(),0)); + return SE.getIntegerSCEV(0, getType()); if (isAffine()) { // If this is an affine expression then we have this situation: diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index abfe94dc80b..2a73c27405a 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -298,9 +298,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEVHandle *op_begin, GepIndices.push_back(ConstantInt::get(Type::Int32Ty, ElIdx)); ElTy = STy->getTypeAtIndex(ElIdx); Ops[0] = - SE.getConstant(ConstantInt::get(Ty, - FullOffset - - SL.getElementOffset(ElIdx))); + SE.getConstant(Ty, FullOffset - SL.getElementOffset(ElIdx)); AnyNonZeroIndices = true; continue; } diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 45f97b8f64b..17ffa2d2de6 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -52,11 +52,12 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, assert(V && "No Value?"); assert(Depth <= MaxDepth && "Limit Search Depth"); unsigned BitWidth = Mask.getBitWidth(); - assert((V->getType()->isInteger() || isa(V->getType())) && + assert((V->getType()->isIntOrIntVector() || isa(V->getType())) && "Not integer or pointer type!"); - assert((!TD || TD->getTypeSizeInBits(V->getType()) == BitWidth) && - (!isa(V->getType()) || - V->getType()->getPrimitiveSizeInBits() == BitWidth) && + assert((!TD || + TD->getTypeSizeInBits(V->getType()->getScalarType()) == BitWidth) && + (!V->getType()->isIntOrIntVector() || + V->getType()->getScalarSizeInBits() == BitWidth) && KnownZero.getBitWidth() == BitWidth && KnownOne.getBitWidth() == BitWidth && "V, Mask, KnownOne and KnownZero should have same BitWidth"); @@ -67,12 +68,26 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, KnownZero = ~KnownOne & Mask; return; } - // Null is all-zeros. - if (isa(V)) { + // Null and aggregate-zero are all-zeros. + if (isa(V) || + isa(V)) { KnownOne.clear(); KnownZero = Mask; return; } + // Handle a constant vector by taking the intersection of the known bits of + // each element. + if (ConstantVector *CV = dyn_cast(V)) { + KnownZero.set(); KnownOne.set(); + for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) { + APInt KnownZero2(BitWidth, 0), KnownOne2(BitWidth, 0); + ComputeMaskedBits(CV->getOperand(i), Mask, KnownZero2, KnownOne2, + TD, Depth); + KnownZero &= KnownZero2; + KnownOne &= KnownOne2; + } + return; + } // The address of an aligned GlobalValue has trailing zeros. if (GlobalValue *GV = dyn_cast(V)) { unsigned Align = GV->getAlignment(); @@ -218,7 +233,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, const Type *SrcTy = I->getOperand(0)->getType(); unsigned SrcBitWidth = TD ? TD->getTypeSizeInBits(SrcTy) : - SrcTy->getPrimitiveSizeInBits(); + SrcTy->getScalarSizeInBits(); APInt MaskIn(Mask); MaskIn.zextOrTrunc(SrcBitWidth); KnownZero.zextOrTrunc(SrcBitWidth); @@ -480,7 +495,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, // Handle array index arithmetic. const Type *IndexedTy = GTI.getIndexedType(); if (!IndexedTy->isSized()) return; - unsigned GEPOpiBits = Index->getType()->getPrimitiveSizeInBits(); + unsigned GEPOpiBits = Index->getType()->getScalarSizeInBits(); uint64_t TypeSize = TD ? TD->getTypeAllocSize(IndexedTy) : 1; LocalMask = APInt::getAllOnesValue(GEPOpiBits); LocalKnownZero = LocalKnownOne = APInt(GEPOpiBits, 0); @@ -609,8 +624,8 @@ bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask, /// 'Op' must have a scalar integer type. /// unsigned llvm::ComputeNumSignBits(Value *V, TargetData *TD, unsigned Depth) { - const IntegerType *Ty = cast(V->getType()); - unsigned TyBits = Ty->getBitWidth(); + const Type *Ty = V->getType(); + unsigned TyBits = Ty->getScalarSizeInBits(); unsigned Tmp, Tmp2; unsigned FirstAnswer = 1; diff --git a/lib/Transforms/Instrumentation/RSProfiling.cpp b/lib/Transforms/Instrumentation/RSProfiling.cpp index c6cf4dfd6eb..b110f4eb368 100644 --- a/lib/Transforms/Instrumentation/RSProfiling.cpp +++ b/lib/Transforms/Instrumentation/RSProfiling.cpp @@ -108,9 +108,9 @@ namespace { class VISIBILITY_HIDDEN GlobalRandomCounter : public Chooser { GlobalVariable* Counter; Value* ResetValue; - const Type* T; + const IntegerType* T; public: - GlobalRandomCounter(Module& M, const Type* t, uint64_t resetval); + GlobalRandomCounter(Module& M, const IntegerType* t, uint64_t resetval); virtual ~GlobalRandomCounter(); virtual void PrepFunction(Function* F); virtual void ProcessChoicePoint(BasicBlock* bb); @@ -121,9 +121,9 @@ namespace { GlobalVariable* Counter; Value* ResetValue; AllocaInst* AI; - const Type* T; + const IntegerType* T; public: - GlobalRandomCounterOpt(Module& M, const Type* t, uint64_t resetval); + GlobalRandomCounterOpt(Module& M, const IntegerType* t, uint64_t resetval); virtual ~GlobalRandomCounterOpt(); virtual void PrepFunction(Function* F); virtual void ProcessChoicePoint(BasicBlock* bb); @@ -193,7 +193,7 @@ static void getBackEdges(Function& F, T& BackEdges); // Methods of choosing when to profile /////////////////////////////////////// -GlobalRandomCounter::GlobalRandomCounter(Module& M, const Type* t, +GlobalRandomCounter::GlobalRandomCounter(Module& M, const IntegerType* t, uint64_t resetval) : T(t) { ConstantInt* Init = ConstantInt::get(T, resetval); ResetValue = Init; @@ -229,7 +229,7 @@ void GlobalRandomCounter::ProcessChoicePoint(BasicBlock* bb) { ReplacePhiPred(oldnext, bb, resetblock); } -GlobalRandomCounterOpt::GlobalRandomCounterOpt(Module& M, const Type* t, +GlobalRandomCounterOpt::GlobalRandomCounterOpt(Module& M, const IntegerType* t, uint64_t resetval) : AI(0), T(t) { ConstantInt* Init = ConstantInt::get(T, resetval); diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 21d393999f9..8115a0f0ffa 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -390,7 +390,7 @@ namespace { Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned); - bool CanEvaluateInDifferentType(Value *V, const IntegerType *Ty, + bool CanEvaluateInDifferentType(Value *V, const Type *Ty, unsigned CastOpc, int &NumCastsRemoved); unsigned GetOrEnforceKnownAlignment(Value *V, unsigned PrefAlign = 0); @@ -654,30 +654,12 @@ static unsigned getOpcode(const Value *V) { } /// AddOne - Add one to a ConstantInt -static ConstantInt *AddOne(ConstantInt *C) { - APInt Val(C->getValue()); - return ConstantInt::get(++Val); +static Constant *AddOne(Constant *C) { + return ConstantExpr::getAdd(C, ConstantInt::get(C->getType(), 1)); } /// SubOne - Subtract one from a ConstantInt -static ConstantInt *SubOne(ConstantInt *C) { - APInt Val(C->getValue()); - return ConstantInt::get(--Val); -} -/// Add - Add two ConstantInts together -static ConstantInt *Add(ConstantInt *C1, ConstantInt *C2) { - return ConstantInt::get(C1->getValue() + C2->getValue()); -} -/// And - Bitwise AND two ConstantInts together -static ConstantInt *And(ConstantInt *C1, ConstantInt *C2) { - return ConstantInt::get(C1->getValue() & C2->getValue()); -} -/// Subtract - Subtract one ConstantInt from another -static ConstantInt *Subtract(ConstantInt *C1, ConstantInt *C2) { - return ConstantInt::get(C1->getValue() - C2->getValue()); -} -/// Multiply - Multiply two ConstantInts together -static ConstantInt *Multiply(ConstantInt *C1, ConstantInt *C2) { - return ConstantInt::get(C1->getValue() * C2->getValue()); +static Constant *SubOne(ConstantInt *C) { + return ConstantExpr::getSub(C, ConstantInt::get(C->getType(), 1)); } /// MultiplyOverflows - True if the multiply can not be expressed in an int /// this size. @@ -774,7 +756,7 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const APInt &KnownZero, /// SimplifyDemandedBits knows about. See if the instruction has any /// properties that allow us to simplify its operands. bool InstCombiner::SimplifyDemandedInstructionBits(Instruction &Inst) { - unsigned BitWidth = cast(Inst.getType())->getBitWidth(); + unsigned BitWidth = Inst.getType()->getScalarSizeInBits(); APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); APInt DemandedMask(APInt::getAllOnesValue(BitWidth)); @@ -830,13 +812,13 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, const Type *VTy = V->getType(); assert((TD || !isa(VTy)) && "SimplifyDemandedBits needs to know bit widths!"); - assert((!TD || TD->getTypeSizeInBits(VTy) == BitWidth) && - (!isa(VTy) || - VTy->getPrimitiveSizeInBits() == BitWidth) && + assert((!TD || TD->getTypeSizeInBits(VTy->getScalarType()) == BitWidth) && + (!VTy->isIntOrIntVector() || + VTy->getScalarSizeInBits() == BitWidth) && KnownZero.getBitWidth() == BitWidth && KnownOne.getBitWidth() == BitWidth && - "Value *V, DemandedMask, KnownZero and KnownOne \ - must have same BitWidth"); + "Value *V, DemandedMask, KnownZero and KnownOne " + "must have same BitWidth"); if (ConstantInt *CI = dyn_cast(V)) { // We know all of the bits for a constant! KnownOne = CI->getValue() & DemandedMask; @@ -1089,7 +1071,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, RHSKnownZero &= LHSKnownZero; break; case Instruction::Trunc: { - unsigned truncBf = I->getOperand(0)->getType()->getPrimitiveSizeInBits(); + unsigned truncBf = I->getOperand(0)->getType()->getScalarSizeInBits(); DemandedMask.zext(truncBf); RHSKnownZero.zext(truncBf); RHSKnownOne.zext(truncBf); @@ -1112,7 +1094,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, break; case Instruction::ZExt: { // Compute the bits in the result that are not present in the input. - unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits(); + unsigned SrcBitWidth =I->getOperand(0)->getType()->getScalarSizeInBits(); DemandedMask.trunc(SrcBitWidth); RHSKnownZero.trunc(SrcBitWidth); @@ -1130,7 +1112,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, } case Instruction::SExt: { // Compute the bits in the result that are not present in the input. - unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits(); + unsigned SrcBitWidth =I->getOperand(0)->getType()->getScalarSizeInBits(); APInt InputDemandedBits = DemandedMask & APInt::getLowBitsSet(BitWidth, SrcBitWidth); @@ -2087,7 +2069,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { // See if SimplifyDemandedBits can simplify this. This handles stuff like // (X & 254)+1 -> (X&254)|1 - if (!isa(I.getType()) && SimplifyDemandedInstructionBits(I)) + if (SimplifyDemandedInstructionBits(I)) return &I; // zext(i1) - 1 -> select i1, 0, -1 @@ -2107,7 +2089,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { Value *XorLHS = 0; if (isa(RHSC) && match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { - uint32_t TySizeBits = I.getType()->getPrimitiveSizeInBits(); + uint32_t TySizeBits = I.getType()->getScalarSizeInBits(); const APInt& RHSVal = cast(RHSC)->getValue(); uint32_t Size = TySizeBits / 2; @@ -2197,7 +2179,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { // X*C1 + X*C2 --> X * (C1+C2) ConstantInt *C1; if (X == dyn_castFoldableMul(RHS, C1)) - return BinaryOperator::CreateMul(X, Add(C1, C2)); + return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, C2)); } // X + X*C --> X * (C+1) @@ -2262,7 +2244,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { // (X & FF00) + xx00 -> (X+xx00) & FF00 if (LHS->hasOneUse() && match(LHS, m_And(m_Value(X), m_ConstantInt(C2)))) { - Constant *Anded = And(CRHS, C2); + Constant *Anded = ConstantExpr::getAnd(CRHS, C2); if (Anded == CRHS) { // See if all bits from the first bit set in the Add RHS up are included // in the mask. First, get the rightmost bit. @@ -2299,7 +2281,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { Other = LHS; } if (CI && CI->getType()->isSized() && - (CI->getType()->getPrimitiveSizeInBits() == + (CI->getType()->getScalarSizeInBits() == TD->getIntPtrType()->getPrimitiveSizeInBits()) && isa(CI->getOperand(0)->getType())) { unsigned AS = @@ -2523,7 +2505,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { else if (ConstantInt *CI1 = dyn_cast(I.getOperand(0))) { if (ConstantInt *CI2 = dyn_cast(Op1I->getOperand(1))) // C1-(X+C2) --> (C1-C2)-X - return BinaryOperator::CreateSub(Subtract(CI1, CI2), + return BinaryOperator::CreateSub(ConstantExpr::getSub(CI1, CI2), Op1I->getOperand(0)); } } @@ -2564,7 +2546,8 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { // X - X*C --> X * (1-C) ConstantInt *C2 = 0; if (dyn_castFoldableMul(Op1I, C2) == Op0) { - Constant *CP1 = Subtract(ConstantInt::get(I.getType(), 1), C2); + Constant *CP1 = ConstantExpr::getSub(ConstantInt::get(I.getType(), 1), + C2); return BinaryOperator::CreateMul(Op0, CP1); } } @@ -2589,7 +2572,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { ConstantInt *C2; // X*C1 - X*C2 -> X * (C1-C2) if (X == dyn_castFoldableMul(Op1, C2)) - return BinaryOperator::CreateMul(X, Subtract(C1, C2)); + return BinaryOperator::CreateMul(X, ConstantExpr::getSub(C1, C2)); } return 0; } @@ -2950,12 +2933,12 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) { // (sdiv X, X) --> 1 (udiv X, X) --> 1 if (Op0 == Op1) { if (const VectorType *Ty = dyn_cast(I.getType())) { - ConstantInt *CI = ConstantInt::get(Ty->getElementType(), 1); + Constant *CI = ConstantInt::get(Ty->getElementType(), 1); std::vector Elts(Ty->getNumElements(), CI); return ReplaceInstUsesWith(I, ConstantVector::get(Elts)); } - ConstantInt *CI = ConstantInt::get(I.getType(), 1); + Constant *CI = ConstantInt::get(I.getType(), 1); return ReplaceInstUsesWith(I, CI); } @@ -2980,7 +2963,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) { return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); else return BinaryOperator::Create(I.getOpcode(), LHS->getOperand(0), - Multiply(RHS, LHSRHS)); + ConstantExpr::getMul(RHS, LHSRHS)); } if (!RHS->isZero()) { // avoid X udiv 0 @@ -3513,7 +3496,7 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op, Value *X = Op->getOperand(0); Constant *Together = 0; if (!Op->isShift()) - Together = And(AndRHS, OpRHS); + Together = ConstantExpr::getAnd(AndRHS, OpRHS); switch (Op->getOpcode()) { case Instruction::Xor: @@ -3724,7 +3707,7 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS, switch (LHSI->getOpcode()) { default: return 0; case Instruction::And: - if (And(N, Mask) == Mask) { + if (ConstantExpr::getAnd(N, Mask) == Mask) { // If the AndRHS is a power of two minus one (0+1+), this is simple. if ((Mask->getValue().countLeadingZeros() + Mask->getValue().countPopulation()) == @@ -3748,7 +3731,7 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS, // If the AndRHS is a power of two minus one (0+1+), and N&Mask == 0 if ((Mask->getValue().countLeadingZeros() + Mask->getValue().countPopulation()) == Mask->getValue().getBitWidth() - && And(N, Mask)->isZero()) + && ConstantExpr::getAnd(N, Mask)->isNullValue()) break; return 0; } @@ -3946,10 +3929,9 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. - if (!isa(I.getType())) { - if (SimplifyDemandedInstructionBits(I)) - return &I; - } else { + if (SimplifyDemandedInstructionBits(I)) + return &I; + if (isa(I.getType())) { if (ConstantVector *CP = dyn_cast(Op1)) { if (CP->isAllOnesValue()) // X & <-1,-1> -> X return ReplaceInstUsesWith(I, I.getOperand(0)); @@ -3957,7 +3939,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { return ReplaceInstUsesWith(I, Op1); // X & <0,0> -> <0,0> } } - + if (ConstantInt *AndRHS = dyn_cast(Op1)) { const APInt& AndRHSMask = AndRHS->getValue(); APInt NotAndRHS(~AndRHSMask); @@ -4510,7 +4492,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, Instruction *Add = BinaryOperator::CreateAdd(Val, AddCST, Val->getName()+".off"); InsertNewInstBefore(Add, I); - AddCST = Subtract(AddOne(RHSCst), LHSCst); + AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst); return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST); } break; // (X == 13 | X == 15) -> no change @@ -4653,18 +4635,17 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. - if (!isa(I.getType())) { - if (SimplifyDemandedInstructionBits(I)) - return &I; - } else if (isa(Op1)) { - return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X - } else if (ConstantVector *CP = dyn_cast(Op1)) { - if (CP->isAllOnesValue()) // X | <-1,-1> -> <-1,-1> - return ReplaceInstUsesWith(I, I.getOperand(1)); + if (SimplifyDemandedInstructionBits(I)) + return &I; + if (isa(I.getType())) { + if (isa(Op1)) { + return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X + } else if (ConstantVector *CP = dyn_cast(Op1)) { + if (CP->isAllOnesValue()) // X | <-1,-1> -> <-1,-1> + return ReplaceInstUsesWith(I, I.getOperand(1)); + } } - - // or X, -1 == -1 if (ConstantInt *RHS = dyn_cast(Op1)) { ConstantInt *C1 = 0; Value *X = 0; @@ -4991,12 +4972,11 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. - if (!isa(I.getType())) { - if (SimplifyDemandedInstructionBits(I)) - return &I; - } else if (isa(Op1)) { - return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X - } + if (SimplifyDemandedInstructionBits(I)) + return &I; + if (isa(I.getType())) + if (isa(Op1)) + return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X // Is this a ~ operation? if (Value *NotOp = dyn_castNotVal(&I)) { @@ -5083,7 +5063,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { Constant *NewRHS = ConstantExpr::getOr(Op0CI, RHS); // Anything in both C1 and C2 is known to be zero, remove it from // NewRHS. - Constant *CommonBits = And(Op0CI, RHS); + Constant *CommonBits = ConstantExpr::getAnd(Op0CI, RHS); NewRHS = ConstantExpr::getAnd(NewRHS, ConstantExpr::getNot(CommonBits)); AddToWorkList(Op0I); @@ -5247,12 +5227,13 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return Changed ? &I : 0; } -/// AddWithOverflow - Compute Result = In1+In2, returning true if the result -/// overflowed for this type. -static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1, - ConstantInt *In2, bool IsSigned = false) { - Result = cast(Add(In1, In2)); +static ConstantInt *ExtractElement(Constant *V, Constant *Idx) { + return cast(ConstantExpr::getExtractElement(V, Idx)); +} +static bool HasAddOverflow(ConstantInt *Result, + ConstantInt *In1, ConstantInt *In2, + bool IsSigned) { if (IsSigned) if (In2->getValue().isNegative()) return Result->getValue().sgt(In1->getValue()); @@ -5262,12 +5243,32 @@ static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1, return Result->getValue().ult(In1->getValue()); } -/// SubWithOverflow - Compute Result = In1-In2, returning true if the result +/// AddWithOverflow - Compute Result = In1+In2, returning true if the result /// overflowed for this type. -static bool SubWithOverflow(ConstantInt *&Result, ConstantInt *In1, - ConstantInt *In2, bool IsSigned = false) { - Result = cast(Subtract(In1, In2)); +static bool AddWithOverflow(Constant *&Result, Constant *In1, + Constant *In2, bool IsSigned = false) { + Result = ConstantExpr::getAdd(In1, In2); + + if (const VectorType *VTy = dyn_cast(In1->getType())) { + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + Constant *Idx = ConstantInt::get(Type::Int32Ty, i); + if (HasAddOverflow(ExtractElement(Result, Idx), + ExtractElement(In1, Idx), + ExtractElement(In2, Idx), + IsSigned)) + return true; + } + return false; + } + return HasAddOverflow(cast(Result), + cast(In1), cast(In2), + IsSigned); +} + +static bool HasSubOverflow(ConstantInt *Result, + ConstantInt *In1, ConstantInt *In2, + bool IsSigned) { if (IsSigned) if (In2->getValue().isNegative()) return Result->getValue().slt(In1->getValue()); @@ -5277,6 +5278,29 @@ static bool SubWithOverflow(ConstantInt *&Result, ConstantInt *In1, return Result->getValue().ugt(In1->getValue()); } +/// SubWithOverflow - Compute Result = In1-In2, returning true if the result +/// overflowed for this type. +static bool SubWithOverflow(Constant *&Result, Constant *In1, + Constant *In2, bool IsSigned = false) { + Result = ConstantExpr::getSub(In1, In2); + + if (const VectorType *VTy = dyn_cast(In1->getType())) { + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + Constant *Idx = ConstantInt::get(Type::Int32Ty, i); + if (HasSubOverflow(ExtractElement(Result, Idx), + ExtractElement(In1, Idx), + ExtractElement(In2, Idx), + IsSigned)) + return true; + } + return false; + } + + return HasSubOverflow(cast(Result), + cast(In1), cast(In2), + IsSigned); +} + /// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the /// code necessary to compute the offset from the base pointer (without adding /// in the base pointer). Return the result as a signed integer of intptr size. @@ -5589,7 +5613,7 @@ Instruction *InstCombiner::FoldFCmp_IntToFP_Cst(FCmpInst &I, // Check to see that the input is converted from an integer type that is small // enough that preserves all bits. TODO: check here for "known" sign bits. // This would allow us to handle (fptosi (x >>s 62) to float) if x is i64 f.e. - unsigned InputSize = LHSI->getOperand(0)->getType()->getPrimitiveSizeInBits(); + unsigned InputSize = LHSI->getOperand(0)->getType()->getScalarSizeInBits(); // If this is a uitofp instruction, we need an extra bit to hold the sign. bool LHSUnsigned = isa(LHSI); @@ -5644,7 +5668,7 @@ Instruction *InstCombiner::FoldFCmp_IntToFP_Cst(FCmpInst &I, // See if the FP constant is too large for the integer. For example, // comparing an i8 to 300.0. - unsigned IntWidth = IntTy->getPrimitiveSizeInBits(); + unsigned IntWidth = IntTy->getScalarSizeInBits(); if (!LHSUnsigned) { // If the RHS value is > SignedMax, fold the comparison. This handles +INF @@ -6459,7 +6483,7 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI, // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and // C2 (CI). By solving for X we can turn this into a range check // instead of computing a divide. - ConstantInt *Prod = Multiply(CmpRHS, DivRHS); + Constant *Prod = ConstantExpr::getMul(CmpRHS, DivRHS); // Determine if the product overflows by seeing if the product is // not equal to the divide. Make sure we do the same kind of divide @@ -6478,7 +6502,7 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI, // overflow variable is set to 0 if it's corresponding bound variable is valid // -1 if overflowed off the bottom end, or +1 if overflowed off the top end. int LoOverflow = 0, HiOverflow = 0; - ConstantInt *LoBound = 0, *HiBound = 0; + Constant *LoBound = 0, *HiBound = 0; if (!DivIsSigned) { // udiv // e.g. X/5 op 3 --> [15, 20) @@ -6966,7 +6990,7 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, if (ConstantInt *BOp1C = dyn_cast(BO->getOperand(1))) { if (BO->hasOneUse()) return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), - Subtract(RHS, BOp1C)); + ConstantExpr::getSub(RHS, BOp1C)); } else if (RHSV == 0) { // Replace ((add A, B) != 0) with (A != -B) if A or B is // efficiently invertible, or if the add has just this one use. @@ -7250,7 +7274,7 @@ Instruction *InstCombiner::commonShiftTransforms(BinaryOperator &I) { } // See if we can fold away this shift. - if (!isa(I.getType()) && SimplifyDemandedInstructionBits(I)) + if (SimplifyDemandedInstructionBits(I)) return &I; // Try to fold constant and into select arguments. @@ -7729,7 +7753,8 @@ Instruction *InstCombiner::PromoteCastOfAllocation(BitCastInst &CI, // If the allocation size is constant, form a constant mul expression Amt = ConstantInt::get(Type::Int32Ty, Scale); if (isa(NumElements)) - Amt = Multiply(cast(NumElements), cast(Amt)); + Amt = ConstantExpr::getMul(cast(NumElements), + cast(Amt)); // otherwise multiply the amount and the number of elements else { Instruction *Tmp = BinaryOperator::CreateMul(Amt, NumElements, "tmp"); @@ -7788,17 +7813,17 @@ Instruction *InstCombiner::PromoteCastOfAllocation(BitCastInst &CI, /// If CastOpc is a sext or zext, we are asking if the low bits of the value can /// bit computed in a larger type, which is then and'd or sext_in_reg'd to get /// the final result. -bool InstCombiner::CanEvaluateInDifferentType(Value *V, const IntegerType *Ty, +bool InstCombiner::CanEvaluateInDifferentType(Value *V, const Type *Ty, unsigned CastOpc, int &NumCastsRemoved){ // We can always evaluate constants in another type. - if (isa(V)) + if (isa(V)) return true; Instruction *I = dyn_cast(V); if (!I) return false; - const IntegerType *OrigTy = cast(V->getType()); + const Type *OrigTy = V->getType(); // If this is an extension or truncate, we can often eliminate it. if (isa(I) || isa(I) || isa(I)) { @@ -7836,8 +7861,8 @@ bool InstCombiner::CanEvaluateInDifferentType(Value *V, const IntegerType *Ty, // If we are truncating the result of this SHL, and if it's a shift of a // constant amount, we can always perform a SHL in a smaller type. if (ConstantInt *CI = dyn_cast(I->getOperand(1))) { - uint32_t BitWidth = Ty->getBitWidth(); - if (BitWidth < OrigTy->getBitWidth() && + uint32_t BitWidth = Ty->getScalarSizeInBits(); + if (BitWidth < OrigTy->getScalarSizeInBits() && CI->getLimitedValue(BitWidth) < BitWidth) return CanEvaluateInDifferentType(I->getOperand(0), Ty, CastOpc, NumCastsRemoved); @@ -7848,8 +7873,8 @@ bool InstCombiner::CanEvaluateInDifferentType(Value *V, const IntegerType *Ty, // lshr iff we know that the bits we would otherwise be shifting in are // already zeros. if (ConstantInt *CI = dyn_cast(I->getOperand(1))) { - uint32_t OrigBitWidth = OrigTy->getBitWidth(); - uint32_t BitWidth = Ty->getBitWidth(); + uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits(); + uint32_t BitWidth = Ty->getScalarSizeInBits(); if (BitWidth < OrigBitWidth && MaskedValueIsZero(I->getOperand(0), APInt::getHighBitsSet(OrigBitWidth, OrigBitWidth-BitWidth)) && @@ -8131,8 +8156,8 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { Value *Src = CI.getOperand(0); const Type *SrcTy = Src->getType(); const Type *DestTy = CI.getType(); - uint32_t SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - uint32_t DestBitSize = DestTy->getPrimitiveSizeInBits(); + uint32_t SrcBitSize = SrcTy->getScalarSizeInBits(); + uint32_t DestBitSize = DestTy->getScalarSizeInBits(); // See if we can simplify any instructions used by the LHS whose sole // purpose is to compute bits we don't care about. @@ -8151,8 +8176,9 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { // Only do this if the dest type is a simple type, don't convert the // expression tree to something weird like i93 unless the source is also // strange. - (isSafeIntegerType(DestTy) || !isSafeIntegerType(SrcI->getType())) && - CanEvaluateInDifferentType(SrcI, cast(DestTy), + (isSafeIntegerType(DestTy->getScalarType()) || + !isSafeIntegerType(SrcI->getType()->getScalarType())) && + CanEvaluateInDifferentType(SrcI, DestTy, CI.getOpcode(), NumCastsRemoved)) { // If this cast is a truncate, evaluting in a different type always // eliminates the cast, so it is always a win. If this is a zero-extension, @@ -8350,17 +8376,17 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) { Value *Src = CI.getOperand(0); const Type *Ty = CI.getType(); - uint32_t DestBitWidth = Ty->getPrimitiveSizeInBits(); - uint32_t SrcBitWidth = cast(Src->getType())->getBitWidth(); + uint32_t DestBitWidth = Ty->getScalarSizeInBits(); + uint32_t SrcBitWidth = Src->getType()->getScalarSizeInBits(); // Canonicalize trunc x to i1 -> (icmp ne (and x, 1), 0) - if (DestBitWidth == 1) { + if (!isa(Ty) && DestBitWidth == 1) { Constant *One = ConstantInt::get(Src->getType(), 1); Src = InsertNewInstBefore(BinaryOperator::CreateAnd(Src, One, "tmp"), CI); Value *Zero = Constant::getNullValue(Src->getType()); return new ICmpInst(ICmpInst::ICMP_NE, Src, Zero); } - + // Optimize trunc(lshr(), c) to pull the shift through the truncate. ConstantInt *ShAmtV = 0; Value *ShiftOp = 0; @@ -8403,7 +8429,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, Instruction &CI, Value *In = ICI->getOperand(0); Value *Sh = ConstantInt::get(In->getType(), - In->getType()->getPrimitiveSizeInBits()-1); + In->getType()->getScalarSizeInBits()-1); In = InsertNewInstBefore(BinaryOperator::CreateLShr(In, Sh, In->getName()+".lobit"), CI); @@ -8494,28 +8520,30 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) { // Get the sizes of the types involved. We know that the intermediate type // will be smaller than A or C, but don't know the relation between A and C. Value *A = CSrc->getOperand(0); - unsigned SrcSize = A->getType()->getPrimitiveSizeInBits(); - unsigned MidSize = CSrc->getType()->getPrimitiveSizeInBits(); - unsigned DstSize = CI.getType()->getPrimitiveSizeInBits(); + unsigned SrcSize = A->getType()->getScalarSizeInBits(); + unsigned MidSize = CSrc->getType()->getScalarSizeInBits(); + unsigned DstSize = CI.getType()->getScalarSizeInBits(); // If we're actually extending zero bits, then if // SrcSize < DstSize: zext(a & mask) // SrcSize == DstSize: a & mask // SrcSize > DstSize: trunc(a) & mask if (SrcSize < DstSize) { APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize)); - Constant *AndConst = ConstantInt::get(AndValue); + Constant *AndConst = ConstantInt::get(A->getType(), AndValue); Instruction *And = BinaryOperator::CreateAnd(A, AndConst, CSrc->getName()+".mask"); InsertNewInstBefore(And, CI); return new ZExtInst(And, CI.getType()); } else if (SrcSize == DstSize) { APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize)); - return BinaryOperator::CreateAnd(A, ConstantInt::get(AndValue)); + return BinaryOperator::CreateAnd(A, ConstantInt::get(A->getType(), + AndValue)); } else if (SrcSize > DstSize) { Instruction *Trunc = new TruncInst(A, CI.getType(), "tmp"); InsertNewInstBefore(Trunc, CI); APInt AndValue(APInt::getLowBitsSet(DstSize, MidSize)); - return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(AndValue)); + return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Trunc->getType(), + AndValue)); } } @@ -8556,9 +8584,9 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) { // eliminate the trunc/sext pair. if (getOpcode(Src) == Instruction::Trunc) { Value *Op = cast(Src)->getOperand(0); - unsigned OpBits = cast(Op->getType())->getBitWidth(); - unsigned MidBits = cast(Src->getType())->getBitWidth(); - unsigned DestBits = cast(CI.getType())->getBitWidth(); + unsigned OpBits = Op->getType()->getScalarSizeInBits(); + unsigned MidBits = Src->getType()->getScalarSizeInBits(); + unsigned DestBits = CI.getType()->getScalarSizeInBits(); unsigned NumSignBits = ComputeNumSignBits(Op); if (OpBits == DestBits) { @@ -8599,8 +8627,8 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) { BA == CA && isa(A)) { Value *I = cast(A)->getOperand(0); if (I->getType() == CI.getType()) { - unsigned MidSize = Src->getType()->getPrimitiveSizeInBits(); - unsigned SrcDstSize = CI.getType()->getPrimitiveSizeInBits(); + unsigned MidSize = Src->getType()->getScalarSizeInBits(); + unsigned SrcDstSize = CI.getType()->getScalarSizeInBits(); unsigned ShAmt = CA->getZExtValue()+SrcDstSize-MidSize; Constant *ShAmtV = ConstantInt::get(CI.getType(), ShAmt); I = InsertNewInstBefore(BinaryOperator::CreateShl(I, ShAmtV, @@ -8671,11 +8699,11 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) { Value *RHSTrunc = LookThroughFPExtensions(OpI->getOperand(1)); if (LHSTrunc->getType() != SrcTy && RHSTrunc->getType() != SrcTy) { - unsigned DstSize = CI.getType()->getPrimitiveSizeInBits(); + unsigned DstSize = CI.getType()->getScalarSizeInBits(); // If the source types were both smaller than the destination type of // the cast, do this xform. - if (LHSTrunc->getType()->getPrimitiveSizeInBits() <= DstSize && - RHSTrunc->getType()->getPrimitiveSizeInBits() <= DstSize) { + if (LHSTrunc->getType()->getScalarSizeInBits() <= DstSize && + RHSTrunc->getType()->getScalarSizeInBits() <= DstSize) { LHSTrunc = InsertCastBefore(Instruction::FPExt, LHSTrunc, CI.getType(), CI); RHSTrunc = InsertCastBefore(Instruction::FPExt, RHSTrunc, @@ -8706,7 +8734,7 @@ Instruction *InstCombiner::visitFPToUI(FPToUIInst &FI) { // 'X' value would cause an undefined result for the fptoui. if ((isa(OpI) || isa(OpI)) && OpI->getOperand(0)->getType() == FI.getType() && - (int)FI.getType()->getPrimitiveSizeInBits() < /*extra bit for sign */ + (int)FI.getType()->getScalarSizeInBits() < /*extra bit for sign */ OpI->getType()->getFPMantissaWidth()) return ReplaceInstUsesWith(FI, OpI->getOperand(0)); @@ -8726,7 +8754,7 @@ Instruction *InstCombiner::visitFPToSI(FPToSIInst &FI) { // 'X' value would cause an undefined result for the fptoui. if ((isa(OpI) || isa(OpI)) && OpI->getOperand(0)->getType() == FI.getType() && - (int)FI.getType()->getPrimitiveSizeInBits() <= + (int)FI.getType()->getScalarSizeInBits() <= OpI->getType()->getFPMantissaWidth()) return ReplaceInstUsesWith(FI, OpI->getOperand(0)); @@ -8747,7 +8775,7 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) { // trunc to be exposed to other transforms. Don't do this for extending // ptrtoint's, because we don't know if the target sign or zero extends its // pointers. - if (CI.getType()->getPrimitiveSizeInBits() < TD->getPointerSizeInBits()) { + if (CI.getType()->getScalarSizeInBits() < TD->getPointerSizeInBits()) { Value *P = InsertNewInstBefore(new PtrToIntInst(CI.getOperand(0), TD->getIntPtrType(), "tmp"), CI); @@ -8763,7 +8791,7 @@ Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) { // allows the trunc to be exposed to other transforms. Don't do this for // extending inttoptr's, because we don't know if the target sign or zero // extends to pointers. - if (CI.getOperand(0)->getType()->getPrimitiveSizeInBits() > + if (CI.getOperand(0)->getType()->getScalarSizeInBits() > TD->getPointerSizeInBits()) { Value *P = InsertNewInstBefore(new TruncInst(CI.getOperand(0), TD->getIntPtrType(), @@ -9194,7 +9222,7 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI, (Pred == ICmpInst::ICMP_SGT && Op1CV.isAllOnesValue())) { Value *In = ICI->getOperand(0); Value *Sh = ConstantInt::get(In->getType(), - In->getType()->getPrimitiveSizeInBits()-1); + In->getType()->getScalarSizeInBits()-1); In = InsertNewInstBefore(BinaryOperator::CreateAShr(In, Sh, In->getName()+".lobit"), *ICI); @@ -9316,7 +9344,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { // The comparison constant and the result are not neccessarily the // same width. Make an all-ones value by inserting a AShr. Value *X = IC->getOperand(0); - uint32_t Bits = X->getType()->getPrimitiveSizeInBits(); + uint32_t Bits = X->getType()->getScalarSizeInBits(); Constant *ShAmt = ConstantInt::get(X->getType(), Bits-1); Instruction *SRA = BinaryOperator::Create(Instruction::AShr, X, ShAmt, "ones"); @@ -10850,8 +10878,8 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) { static Value *InsertCastToIntPtrTy(Value *V, const Type *DTy, Instruction *InsertPoint, InstCombiner *IC) { - unsigned PtrSize = DTy->getPrimitiveSizeInBits(); - unsigned VTySize = V->getType()->getPrimitiveSizeInBits(); + unsigned PtrSize = DTy->getScalarSizeInBits(); + unsigned VTySize = V->getType()->getScalarSizeInBits(); // We must cast correctly to the pointer type. Ensure that we // sign extend the integer value if it is smaller as this is // used for address computation. @@ -10892,7 +10920,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { const Type *SrcTy = CI->getOperand(0)->getType(); // We can eliminate a cast from i32 to i64 iff the target // is a 32-bit pointer target. - if (SrcTy->getPrimitiveSizeInBits() >= TD->getPointerSizeInBits()) { + if (SrcTy->getScalarSizeInBits() >= TD->getPointerSizeInBits()) { MadeChange = true; *i = CI->getOperand(0); } @@ -11105,7 +11133,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { ConstantInt *Scale = 0; if (ArrayEltSize == 1) { NewIdx = GEP.getOperand(1); - Scale = ConstantInt::get(NewIdx->getType(), 1); + Scale = ConstantInt::get(cast(NewIdx->getType()), 1); } else if (ConstantInt *CI = dyn_cast(GEP.getOperand(1))) { NewIdx = ConstantInt::get(CI->getType(), 1); Scale = CI; @@ -11114,7 +11142,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { isa(Inst->getOperand(1))) { ConstantInt *ShAmt = cast(Inst->getOperand(1)); uint32_t ShAmtVal = ShAmt->getLimitedValue(64); - Scale = ConstantInt::get(Inst->getType(), 1ULL << ShAmtVal); + Scale = ConstantInt::get(cast(Inst->getType()), + 1ULL << ShAmtVal); NewIdx = Inst->getOperand(0); } else if (Inst->getOpcode() == Instruction::Mul && isa(Inst->getOperand(1))) { diff --git a/lib/Transforms/Scalar/LoopIndexSplit.cpp b/lib/Transforms/Scalar/LoopIndexSplit.cpp index 9c785968e1d..6f7a7f866a8 100644 --- a/lib/Transforms/Scalar/LoopIndexSplit.cpp +++ b/lib/Transforms/Scalar/LoopIndexSplit.cpp @@ -290,13 +290,13 @@ static bool isUsedOutsideLoop(Value *V, Loop *L) { // Return V+1 static Value *getPlusOne(Value *V, bool Sign, Instruction *InsertPt) { - ConstantInt *One = ConstantInt::get(V->getType(), 1, Sign); + Constant *One = ConstantInt::get(V->getType(), 1, Sign); return BinaryOperator::CreateAdd(V, One, "lsp", InsertPt); } // Return V-1 static Value *getMinusOne(Value *V, bool Sign, Instruction *InsertPt) { - ConstantInt *One = ConstantInt::get(V->getType(), 1, Sign); + Constant *One = ConstantInt::get(V->getType(), 1, Sign); return BinaryOperator::CreateSub(V, One, "lsp", InsertPt); } diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 5603042617c..540433f7ee5 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -2008,15 +2008,15 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond, if (!isa(NewCmpTy)) NewCmpRHS = ConstantInt::get(NewCmpTy, NewCmpVal); else { - ConstantInt *CI = ConstantInt::get(NewCmpIntTy, NewCmpVal); + Constant *CI = ConstantInt::get(NewCmpIntTy, NewCmpVal); NewCmpRHS = ConstantExpr::getIntToPtr(CI, NewCmpTy); } NewOffset = TyBits == NewTyBits ? SE->getMulExpr(CondUse->getOffset(), - SE->getConstant(ConstantInt::get(CmpTy, Scale))) - : SE->getConstant(ConstantInt::get(NewCmpIntTy, + SE->getConstant(CmpTy, Scale)) + : SE->getConstant(NewCmpIntTy, cast(CondUse->getOffset())->getValue() - ->getSExtValue()*Scale)); + ->getSExtValue()*Scale); break; } } @@ -2242,7 +2242,7 @@ void LoopStrengthReduce::OptimizeShadowIV(Loop *L) { ConstantInt *Init = dyn_cast(PH->getIncomingValue(Entry)); if (!Init) continue; - ConstantFP *NewInit = ConstantFP::get(DestTy, Init->getZExtValue()); + Constant *NewInit = ConstantFP::get(DestTy, Init->getZExtValue()); BinaryOperator *Incr = dyn_cast(PH->getIncomingValue(Latch)); @@ -2266,7 +2266,7 @@ void LoopStrengthReduce::OptimizeShadowIV(Loop *L) { PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH); /* create new increment. '++d' in above example. */ - ConstantFP *CFP = ConstantFP::get(DestTy, C->getZExtValue()); + Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue()); BinaryOperator *NewIncr = BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ? Instruction::FAdd : Instruction::FSub, @@ -2506,7 +2506,7 @@ void LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) { Value *startVal = phi->getIncomingValue(inBlock); Value *endVal = Cond->getOperand(1); // FIXME check for case where both are constant - ConstantInt* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0); + Constant* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0); BinaryOperator *NewStartVal = BinaryOperator::Create(Instruction::Sub, endVal, startVal, "tmp", PreInsertPt); diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 1d293ccbd44..6c392145a50 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -208,6 +208,22 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, } } + // If the cast operand is a constant vector, perform the cast by + // operating on each element. In the cast of bitcasts, the element + // count may be mismatched; don't attempt to handle that here. + if (const ConstantVector *CV = dyn_cast(V)) + if (isa(DestTy) && + cast(DestTy)->getNumElements() == + CV->getType()->getNumElements()) { + std::vector res; + const VectorType *DestVecTy = cast(DestTy); + const Type *DstEltTy = DestVecTy->getElementType(); + for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) + res.push_back(ConstantExpr::getCast(opc, + CV->getOperand(i), DstEltTy)); + return ConstantVector::get(DestVecTy, res); + } + // We actually have to do a cast now. Perform the cast according to the // opcode specified. switch (opc) { @@ -237,14 +253,6 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, APInt Val(DestBitWidth, 2, x); return ConstantInt::get(Val); } - if (const ConstantVector *CV = dyn_cast(V)) { - std::vector res; - const VectorType *DestVecTy = cast(DestTy); - const Type *DstEltTy = DestVecTy->getElementType(); - for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) - res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy)); - return ConstantVector::get(DestVecTy, res); - } return 0; // Can't fold. case Instruction::IntToPtr: //always treated as unsigned if (V->isNullValue()) // Is it an integral null value? @@ -266,14 +274,6 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, APFloat::rmNearestTiesToEven); return ConstantFP::get(apf); } - if (const ConstantVector *CV = dyn_cast(V)) { - std::vector res; - const VectorType *DestVecTy = cast(DestTy); - const Type *DstEltTy = DestVecTy->getElementType(); - for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) - res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy)); - return ConstantVector::get(DestVecTy, res); - } return 0; case Instruction::ZExt: if (const ConstantInt *CI = dyn_cast(V)) { diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 69c503dff95..ffebf1a2ac3 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -269,9 +269,20 @@ typedef DenseMap IntMapTy; static ManagedStatic IntConstants; -ConstantInt *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) { - const IntegerType *ITy = cast(Ty); - return get(APInt(ITy->getBitWidth(), V, isSigned)); +ConstantInt *ConstantInt::get(const IntegerType *Ty, + uint64_t V, bool isSigned) { + return get(APInt(Ty->getBitWidth(), V, isSigned)); +} + +Constant *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) { + Constant *C = get(cast(Ty->getScalarType()), V, isSigned); + + // For vectors, broadcast the value. + if (const VectorType *VTy = dyn_cast(Ty)) + return + ConstantVector::get(std::vector(VTy->getNumElements(), C)); + + return C; } // Get a ConstantInt from an APInt. Note that the value stored in the DenseMap @@ -292,6 +303,19 @@ ConstantInt *ConstantInt::get(const APInt& V) { return Slot = new ConstantInt(ITy, V); } +Constant *ConstantInt::get(const Type *Ty, const APInt &V) { + ConstantInt *C = ConstantInt::get(V); + assert(C->getType() == Ty->getScalarType() && + "ConstantInt type doesn't match the type implied by its value!"); + + // For vectors, broadcast the value. + if (const VectorType *VTy = dyn_cast(Ty)) + return + ConstantVector::get(std::vector(VTy->getNumElements(), C)); + + return C; +} + //===----------------------------------------------------------------------===// // ConstantFP //===----------------------------------------------------------------------===// @@ -391,11 +415,19 @@ ConstantFP *ConstantFP::get(const APFloat &V) { /// get() - This returns a constant fp for the specified value in the /// specified type. This should only be used for simple constant values like /// 2.0/1.0 etc, that are known-valid both as double and as the target format. -ConstantFP *ConstantFP::get(const Type *Ty, double V) { +Constant *ConstantFP::get(const Type *Ty, double V) { APFloat FV(V); bool ignored; - FV.convert(*TypeToFloatSemantics(Ty), APFloat::rmNearestTiesToEven, &ignored); - return get(FV); + FV.convert(*TypeToFloatSemantics(Ty->getScalarType()), + APFloat::rmNearestTiesToEven, &ignored); + Constant *C = get(FV); + + // For vectors, broadcast the value. + if (const VectorType *VTy = dyn_cast(Ty)) + return + ConstantVector::get(std::vector(VTy->getNumElements(), C)); + + return C; } //===----------------------------------------------------------------------===// @@ -1932,19 +1964,19 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { } Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) { - if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return getCast(Instruction::BitCast, C, Ty); return getCast(Instruction::ZExt, C, Ty); } Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) { - if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return getCast(Instruction::BitCast, C, Ty); return getCast(Instruction::SExt, C, Ty); } Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) { - if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return getCast(Instruction::BitCast, C, Ty); return getCast(Instruction::Trunc, C, Ty); } @@ -1960,9 +1992,10 @@ Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) { Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty, bool isSigned) { - assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast"); - unsigned SrcBits = C->getType()->getPrimitiveSizeInBits(); - unsigned DstBits = Ty->getPrimitiveSizeInBits(); + assert(C->getType()->isIntOrIntVector() && + Ty->isIntOrIntVector() && "Invalid cast"); + unsigned SrcBits = C->getType()->getScalarSizeInBits(); + unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::Trunc : @@ -1971,10 +2004,10 @@ Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty, } Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) { - assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && + assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && "Invalid cast"); - unsigned SrcBits = C->getType()->getPrimitiveSizeInBits(); - unsigned DstBits = Ty->getPrimitiveSizeInBits(); + unsigned SrcBits = C->getType()->getScalarSizeInBits(); + unsigned DstBits = Ty->getScalarSizeInBits(); if (SrcBits == DstBits) return C; // Avoid a useless cast Instruction::CastOps opcode = @@ -1983,42 +2016,67 @@ Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) { } Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) { - assert(C->getType()->isInteger() && "Trunc operand must be integer"); - assert(Ty->isInteger() && "Trunc produces only integral"); - assert(C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&& +#ifndef NDEBUG + bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; + bool toVec = Ty->getTypeID() == Type::VectorTyID; +#endif + assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); + assert(C->getType()->isIntOrIntVector() && "Trunc operand must be integer"); + assert(Ty->isIntOrIntVector() && "Trunc produces only integral"); + assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&& "SrcTy must be larger than DestTy for Trunc!"); return getFoldedCast(Instruction::Trunc, C, Ty); } Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) { - assert(C->getType()->isInteger() && "SEXt operand must be integral"); - assert(Ty->isInteger() && "SExt produces only integer"); - assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&& +#ifndef NDEBUG + bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; + bool toVec = Ty->getTypeID() == Type::VectorTyID; +#endif + assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); + assert(C->getType()->isIntOrIntVector() && "SExt operand must be integral"); + assert(Ty->isIntOrIntVector() && "SExt produces only integer"); + assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for SExt!"); return getFoldedCast(Instruction::SExt, C, Ty); } Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) { - assert(C->getType()->isInteger() && "ZEXt operand must be integral"); - assert(Ty->isInteger() && "ZExt produces only integer"); - assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&& +#ifndef NDEBUG + bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; + bool toVec = Ty->getTypeID() == Type::VectorTyID; +#endif + assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); + assert(C->getType()->isIntOrIntVector() && "ZEXt operand must be integral"); + assert(Ty->isIntOrIntVector() && "ZExt produces only integer"); + assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for ZExt!"); return getFoldedCast(Instruction::ZExt, C, Ty); } Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) { - assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && - C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&& +#ifndef NDEBUG + bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; + bool toVec = Ty->getTypeID() == Type::VectorTyID; +#endif + assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); + assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && + C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&& "This is an illegal floating point truncation!"); return getFoldedCast(Instruction::FPTrunc, C, Ty); } Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) { - assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && - C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&& +#ifndef NDEBUG + bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; + bool toVec = Ty->getTypeID() == Type::VectorTyID; +#endif + assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); + assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && + C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "This is an illegal floating point extension!"); return getFoldedCast(Instruction::FPExt, C, Ty); } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 20ab7e91eeb..b1e9aca80a8 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1837,11 +1837,11 @@ bool CastInst::isNoopCast(const Type *IntPtrTy) const { case Instruction::BitCast: return true; // BitCast never modifies bits. case Instruction::PtrToInt: - return IntPtrTy->getPrimitiveSizeInBits() == - getType()->getPrimitiveSizeInBits(); + return IntPtrTy->getScalarSizeInBits() == + getType()->getScalarSizeInBits(); case Instruction::IntToPtr: - return IntPtrTy->getPrimitiveSizeInBits() == - getOperand(0)->getType()->getPrimitiveSizeInBits(); + return IntPtrTy->getScalarSizeInBits() == + getOperand(0)->getType()->getScalarSizeInBits(); } } @@ -1946,8 +1946,8 @@ unsigned CastInst::isEliminableCastPair( return 0; case 7: { // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size - unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits(); - unsigned MidSize = MidTy->getPrimitiveSizeInBits(); + unsigned PtrSize = IntPtrTy->getScalarSizeInBits(); + unsigned MidSize = MidTy->getScalarSizeInBits(); if (MidSize >= PtrSize) return Instruction::BitCast; return 0; @@ -1956,8 +1956,8 @@ unsigned CastInst::isEliminableCastPair( // ext, trunc -> bitcast, if the SrcTy and DstTy are same size // ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy) // ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy) - unsigned SrcSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DstSize = DstTy->getPrimitiveSizeInBits(); + unsigned SrcSize = SrcTy->getScalarSizeInBits(); + unsigned DstSize = DstTy->getScalarSizeInBits(); if (SrcSize == DstSize) return Instruction::BitCast; else if (SrcSize < DstSize) @@ -1985,9 +1985,9 @@ unsigned CastInst::isEliminableCastPair( return 0; case 13: { // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize - unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits(); - unsigned SrcSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DstSize = DstTy->getPrimitiveSizeInBits(); + unsigned PtrSize = IntPtrTy->getScalarSizeInBits(); + unsigned SrcSize = SrcTy->getScalarSizeInBits(); + unsigned DstSize = DstTy->getScalarSizeInBits(); if (SrcSize <= PtrSize && SrcSize == DstSize) return Instruction::BitCast; return 0; @@ -2051,7 +2051,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore) { - if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); return Create(Instruction::ZExt, S, Ty, Name, InsertBefore); } @@ -2059,7 +2059,7 @@ CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) { - if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); return Create(Instruction::ZExt, S, Ty, Name, InsertAtEnd); } @@ -2067,7 +2067,7 @@ CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore) { - if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); return Create(Instruction::SExt, S, Ty, Name, InsertBefore); } @@ -2075,7 +2075,7 @@ CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) { - if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); return Create(Instruction::SExt, S, Ty, Name, InsertAtEnd); } @@ -2083,7 +2083,7 @@ CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore) { - if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); return Create(Instruction::Trunc, S, Ty, Name, InsertBefore); } @@ -2091,7 +2091,7 @@ CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty, CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) { - if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) + if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); return Create(Instruction::Trunc, S, Ty, Name, InsertAtEnd); } @@ -2125,8 +2125,8 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, bool isSigned, const std::string &Name, Instruction *InsertBefore) { assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast"); - unsigned SrcBits = C->getType()->getPrimitiveSizeInBits(); - unsigned DstBits = Ty->getPrimitiveSizeInBits(); + unsigned SrcBits = C->getType()->getScalarSizeInBits(); + unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::Trunc : @@ -2138,8 +2138,8 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, bool isSigned, const std::string &Name, BasicBlock *InsertAtEnd) { assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast"); - unsigned SrcBits = C->getType()->getPrimitiveSizeInBits(); - unsigned DstBits = Ty->getPrimitiveSizeInBits(); + unsigned SrcBits = C->getType()->getScalarSizeInBits(); + unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::Trunc : @@ -2152,8 +2152,8 @@ CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty, Instruction *InsertBefore) { assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && "Invalid cast"); - unsigned SrcBits = C->getType()->getPrimitiveSizeInBits(); - unsigned DstBits = Ty->getPrimitiveSizeInBits(); + unsigned SrcBits = C->getType()->getScalarSizeInBits(); + unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt)); @@ -2165,8 +2165,8 @@ CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty, BasicBlock *InsertAtEnd) { assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && "Invalid cast"); - unsigned SrcBits = C->getType()->getPrimitiveSizeInBits(); - unsigned DstBits = Ty->getPrimitiveSizeInBits(); + unsigned SrcBits = C->getType()->getScalarSizeInBits(); + unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt)); @@ -2183,8 +2183,8 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) { return true; // Get the bit sizes, we'll need these - unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector - unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector + unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr // Run through the possibilities ... if (DestTy->isInteger()) { // Casting to integral @@ -2242,8 +2242,8 @@ CastInst::getCastOpcode( const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) { // Get the bit sizes, we'll need these const Type *SrcTy = Src->getType(); - unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector - unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector + unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() && "Only first class types are castable!"); @@ -2344,8 +2344,8 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) { return false; // Get the size of the types in bits, we'll need this later - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DstBitSize = DstTy->getPrimitiveSizeInBits(); + unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); + unsigned DstBitSize = DstTy->getScalarSizeInBits(); // Switch on the opcode provided switch (op) { @@ -2400,7 +2400,7 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) { // Now we know we're not dealing with a pointer/non-pointer mismatch. In all // these cases, the cast is okay if the source and destination bit widths // are identical. - return SrcBitSize == DstBitSize; + return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits(); } } diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index a1e6c42f86f..620083796f3 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -112,6 +112,14 @@ const Type *Type::getVAArgsPromotedType() const { return this; } +/// getScalarType - If this is a vector type, return the element type, +/// otherwise return this. +const Type *Type::getScalarType() const { + if (const VectorType *VTy = dyn_cast(this)) + return VTy->getElementType(); + return this; +} + /// isIntOrIntVector - Return true if this is an integer type or a vector of /// integer types. /// @@ -174,6 +182,28 @@ unsigned Type::getPrimitiveSizeInBits() const { } } +/// getScalarSizeInBits - If this is a vector type, return the +/// getPrimitiveSizeInBits value for the element type. Otherwise return the +/// getPrimitiveSizeInBits value for this type. +unsigned Type::getScalarSizeInBits() const { + return getScalarType()->getPrimitiveSizeInBits(); +} + +/// getFPMantissaWidth - Return the width of the mantissa of this type. This +/// is only valid on floating point types. If the FP type does not +/// have a stable mantissa (e.g. ppc long double), this method returns -1. +int Type::getFPMantissaWidth() const { + if (const VectorType *VTy = dyn_cast(this)) + return VTy->getElementType()->getFPMantissaWidth(); + assert(isFloatingPoint() && "Not a floating point type!"); + if (ID == FloatTyID) return 24; + if (ID == DoubleTyID) return 53; + if (ID == X86_FP80TyID) return 64; + if (ID == FP128TyID) return 113; + assert(ID == PPC_FP128TyID && "unknown fp type"); + return -1; +} + /// isSizedDerivedType - Derived types like structures and arrays are sized /// iff all of the members of the type are sized as well. Since asking for /// their size is relatively uncommon, move this operation out of line. diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index e9f2acda28d..10816e6248b 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -745,8 +745,8 @@ void Verifier::visitTruncInst(TruncInst &I) { const Type *DestTy = I.getType(); // Get the size of the types in bits, we'll need this later - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); + unsigned DestBitSize = DestTy->getScalarSizeInBits(); Assert1(SrcTy->isIntOrIntVector(), "Trunc only operates on integer", &I); Assert1(DestTy->isIntOrIntVector(), "Trunc only produces integer", &I); @@ -767,8 +767,8 @@ void Verifier::visitZExtInst(ZExtInst &I) { Assert1(DestTy->isIntOrIntVector(), "ZExt only produces an integer", &I); Assert1(isa(SrcTy) == isa(DestTy), "zext source and destination must both be a vector or neither", &I); - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); + unsigned DestBitSize = DestTy->getScalarSizeInBits(); Assert1(SrcBitSize < DestBitSize,"Type too small for ZExt", &I); @@ -781,8 +781,8 @@ void Verifier::visitSExtInst(SExtInst &I) { const Type *DestTy = I.getType(); // Get the size of the types in bits, we'll need this later - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); + unsigned DestBitSize = DestTy->getScalarSizeInBits(); Assert1(SrcTy->isIntOrIntVector(), "SExt only operates on integer", &I); Assert1(DestTy->isIntOrIntVector(), "SExt only produces an integer", &I); @@ -798,8 +798,8 @@ void Verifier::visitFPTruncInst(FPTruncInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); // Get the size of the types in bits, we'll need this later - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); + unsigned DestBitSize = DestTy->getScalarSizeInBits(); Assert1(SrcTy->isFPOrFPVector(),"FPTrunc only operates on FP", &I); Assert1(DestTy->isFPOrFPVector(),"FPTrunc only produces an FP", &I); @@ -816,8 +816,8 @@ void Verifier::visitFPExtInst(FPExtInst &I) { const Type *DestTy = I.getType(); // Get the size of the types in bits, we'll need this later - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); + unsigned DestBitSize = DestTy->getScalarSizeInBits(); Assert1(SrcTy->isFPOrFPVector(),"FPExt only operates on FP", &I); Assert1(DestTy->isFPOrFPVector(),"FPExt only produces an FP", &I); diff --git a/test/Feature/vector-cast-constant-exprs.ll b/test/Feature/vector-cast-constant-exprs.ll new file mode 100644 index 00000000000..ffdc0f080fa --- /dev/null +++ b/test/Feature/vector-cast-constant-exprs.ll @@ -0,0 +1,37 @@ +; RUN: llvm-as < %s | llvm-dis | not grep {ret.*(} + +; All of these constant expressions should fold. + +define <2 x float> @ga() { + ret <2 x float> fptrunc (<2 x double> to <2 x float>) +} +define <2 x double> @gb() { + ret <2 x double> fpext (<2 x float> to <2 x double>) +} +define <2 x i64> @gd() { + ret <2 x i64> zext (<2 x i32> to <2 x i64>) +} +define <2 x i64> @ge() { + ret <2 x i64> sext (<2 x i32> to <2 x i64>) +} +define <2 x i32> @gf() { + ret <2 x i32> trunc (<2 x i64> to <2 x i32>) +} +define <2 x i32> @gh() { + ret <2 x i32> fptoui (<2 x float> to <2 x i32>) +} +define <2 x i32> @gi() { + ret <2 x i32> fptosi (<2 x float> to <2 x i32>) +} +define <2 x float> @gj() { + ret <2 x float> uitofp (<2 x i32> to <2 x float>) +} +define <2 x float> @gk() { + ret <2 x float> sitofp (<2 x i32> to <2 x float>) +} +define <2 x double> @gl() { + ret <2 x double> bitcast (<2 x double> to <2 x double>) +} +define <2 x double> @gm() { + ret <2 x double> bitcast (<2 x i64> to <2 x double>) +} diff --git a/test/Transforms/InstCombine/vector-casts.ll b/test/Transforms/InstCombine/vector-casts.ll new file mode 100644 index 00000000000..ae5b8a9c7c4 --- /dev/null +++ b/test/Transforms/InstCombine/vector-casts.ll @@ -0,0 +1,55 @@ +; RUN: llvm-as < %s | opt -instcombine + +define void @convert(<2 x i32>* %dst.addr, <2 x i64> %src) nounwind { +entry: + %val = trunc <2 x i64> %src to <2 x i32> ; <<2 x i32>> [#uses=1] + %add = add <2 x i32> %val, ; <<2 x i32>> [#uses=1] + store <2 x i32> %add, <2 x i32>* %dst.addr + ret void +} + +define <2 x i65> @foo(<2 x i64> %t) { + %a = trunc <2 x i64> %t to <2 x i32> + %b = zext <2 x i32> %a to <2 x i65> + ret <2 x i65> %b +} +define <2 x i64> @bar(<2 x i65> %t) { + %a = trunc <2 x i65> %t to <2 x i32> + %b = zext <2 x i32> %a to <2 x i64> + ret <2 x i64> %b +} +define <2 x i65> @foos(<2 x i64> %t) { + %a = trunc <2 x i64> %t to <2 x i32> + %b = sext <2 x i32> %a to <2 x i65> + ret <2 x i65> %b +} +define <2 x i64> @bars(<2 x i65> %t) { + %a = trunc <2 x i65> %t to <2 x i32> + %b = sext <2 x i32> %a to <2 x i64> + ret <2 x i64> %b +} +define <2 x i64> @quxs(<2 x i64> %t) { + %a = trunc <2 x i64> %t to <2 x i32> + %b = sext <2 x i32> %a to <2 x i64> + ret <2 x i64> %b +} +define <2 x i64> @quxt(<2 x i64> %t) { + %a = shl <2 x i64> %t, + %b = ashr <2 x i64> %a, + ret <2 x i64> %b +} +define <2 x double> @fa(<2 x double> %t) { + %a = fptrunc <2 x double> %t to <2 x float> + %b = fpext <2 x float> %a to <2 x double> + ret <2 x double> %b +} +define <2 x double> @fb(<2 x double> %t) { + %a = fptoui <2 x double> %t to <2 x i64> + %b = uitofp <2 x i64> %a to <2 x double> + ret <2 x double> %b +} +define <2 x double> @fc(<2 x double> %t) { + %a = fptosi <2 x double> %t to <2 x i64> + %b = sitofp <2 x i64> %a to <2 x double> + ret <2 x double> %b +} -- 2.34.1