From a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 27 Jan 2012 03:08:05 +0000 Subject: [PATCH] continue making the world safe for ConstantDataVector. At this point, we should (theoretically optimize and codegen ConstantDataVector as well as ConstantVector. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149116 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/SelectionDAGBuilder.cpp | 2 +- lib/Transforms/IPO/GlobalOpt.cpp | 2 +- .../InstCombine/InstCombineCalls.cpp | 15 +++-- .../InstCombine/InstCombineMulDivRem.cpp | 35 +++++++--- .../InstCombineSimplifyDemanded.cpp | 2 +- .../InstCombine/InstCombineVectorOps.cpp | 31 ++++----- .../InstCombine/InstructionCombining.cpp | 12 ++-- lib/VMCore/ConstantFold.cpp | 66 +++++++++++-------- lib/VMCore/Constants.cpp | 12 ++-- lib/VMCore/Instructions.cpp | 6 +- 10 files changed, 108 insertions(+), 75 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index bc807dedc61..0f96c2d98c8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6061,7 +6061,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { // constant pool entry to get its address. const Value *OpVal = OpInfo.CallOperandVal; if (isa(OpVal) || isa(OpVal) || - isa(OpVal)) { + isa(OpVal) || isa(OpVal)) { OpInfo.CallOperand = DAG.getConstantPool(cast(OpVal), TLI.getPointerTy()); } else { diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 4a98b3b36f0..2f963d15835 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -2174,7 +2174,7 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, return Val; } - std::vector Elts; + SmallVector Elts; if (StructType *STy = dyn_cast(Init->getType())) { // Break up the constant into its elements. for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index db31e9144a8..a87fbbd9895 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -623,14 +623,16 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { case Intrinsic::ppc_altivec_vperm: // Turn vperm(V1,V2,mask) -> shuffle(V1,V2,mask) if mask is a constant. - if (ConstantVector *Mask = dyn_cast(II->getArgOperand(2))) { - assert(Mask->getNumOperands() == 16 && "Bad type for intrinsic!"); + if (Constant *Mask = dyn_cast(II->getArgOperand(2))) { + assert(Mask->getType()->getVectorNumElements() == 16 && + "Bad type for intrinsic!"); // Check that all of the elements are integer constants or undefs. bool AllEltsOk = true; for (unsigned i = 0; i != 16; ++i) { - if (!isa(Mask->getOperand(i)) && - !isa(Mask->getOperand(i))) { + Constant *Elt = Mask->getAggregateElement(i); + if (Elt == 0 || + !(isa(Elt) || isa(Elt))) { AllEltsOk = false; break; } @@ -649,9 +651,10 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { memset(ExtractedElts, 0, sizeof(ExtractedElts)); for (unsigned i = 0; i != 16; ++i) { - if (isa(Mask->getOperand(i))) + if (isa(Mask->getAggregateElement(i))) continue; - unsigned Idx=cast(Mask->getOperand(i))->getZExtValue(); + unsigned Idx = + cast(Mask->getAggregateElement(i))->getZExtValue(); Idx &= 31; // Match the hardware behavior. if (ExtractedElts[Idx] == 0) { diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 122f9486c8e..60be1ddca27 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -264,6 +264,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { if (Op1F->isExactlyValue(1.0)) return ReplaceInstUsesWith(I, Op0); // Eliminate 'fmul double %X, 1.0' } else if (Op1C->getType()->isVectorTy()) { + // FIXME: Remove. if (ConstantVector *Op1V = dyn_cast(Op1C)) { // As above, vector X*splat(1.0) -> X in all defined cases. if (Constant *Splat = Op1V->getSplatValue()) { @@ -272,6 +273,14 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { return ReplaceInstUsesWith(I, Op0); } } + if (ConstantDataVector *Op1V = dyn_cast(Op1C)) { + // As above, vector X*splat(1.0) -> X in all defined cases. + if (Constant *Splat = Op1V->getSplatValue()) { + if (ConstantFP *F = dyn_cast(Splat)) + if (F->isExactlyValue(1.0)) + return ReplaceInstUsesWith(I, Op0); + } + } } // Try to fold constant mul into select arguments. @@ -688,28 +697,36 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) { } // If it's a constant vector, flip any negative values positive. - if (ConstantVector *RHSV = dyn_cast(Op1)) { - unsigned VWidth = RHSV->getNumOperands(); + if (isa(Op1) || isa(Op1)) { + Constant *C = cast(Op1); + unsigned VWidth = C->getType()->getVectorNumElements(); bool hasNegative = false; - for (unsigned i = 0; !hasNegative && i != VWidth; ++i) - if (ConstantInt *RHS = dyn_cast(RHSV->getOperand(i))) + bool hasMissing = false; + for (unsigned i = 0; i != VWidth; ++i) { + Constant *Elt = C->getAggregateElement(i); + if (Elt == 0) { + hasMissing = true; + break; + } + + if (ConstantInt *RHS = dyn_cast(Elt)) if (RHS->isNegative()) hasNegative = true; + } - if (hasNegative) { + if (hasNegative && !hasMissing) { SmallVector Elts(VWidth); for (unsigned i = 0; i != VWidth; ++i) { - if (ConstantInt *RHS = dyn_cast(RHSV->getOperand(i))) { + Elts[i] = C->getAggregateElement(i); + if (ConstantInt *RHS = dyn_cast(Elts[i])) { if (RHS->isNegative()) Elts[i] = cast(ConstantExpr::getNeg(RHS)); - else - Elts[i] = RHS; } } Constant *NewRHSV = ConstantVector::get(Elts); - if (NewRHSV != RHSV) { + if (NewRHSV != C) { // Don't loop on -MININT Worklist.AddValue(I.getOperand(1)); I.setOperand(1, NewRHSV); return &I; diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 6873d15baba..61a8e5b3bce 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -982,7 +982,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, if (NewUndefElts) { // Add additional discovered undefs. - std::vector Elts; + SmallVector Elts; for (unsigned i = 0; i < VWidth; ++i) { if (UndefElts[i]) Elts.push_back(UndefValue::get(Type::getInt32Ty(I->getContext()))); diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 050cb48d379..cf60f0f426d 100644 --- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -207,7 +207,7 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { /// elements from either LHS or RHS, return the shuffle mask and true. /// Otherwise, return false. static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS, - std::vector &Mask) { + SmallVectorImpl &Mask) { assert(V->getType() == LHS->getType() && V->getType() == RHS->getType() && "Invalid CollectSingleShuffleElements"); unsigned NumElts = cast(V->getType())->getNumElements(); @@ -284,7 +284,7 @@ static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS, /// CollectShuffleElements - We are building a shuffle of V, using RHS as the /// RHS of the shuffle instruction, if it is not null. Return a shuffle mask /// that computes V and the LHS value of the shuffle. -static Value *CollectShuffleElements(Value *V, std::vector &Mask, +static Value *CollectShuffleElements(Value *V, SmallVectorImpl &Mask, Value *&RHS) { assert(V->getType()->isVectorTy() && (RHS == 0 || V->getType() == RHS->getType()) && @@ -384,7 +384,7 @@ Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) { // If this insertelement isn't used by some other insertelement, turn it // (and any insertelements it points to), into one big shuffle. if (!IE.hasOneUse() || !isa(IE.use_back())) { - std::vector Mask; + SmallVector Mask; Value *RHS = 0; Value *LHS = CollectShuffleElements(&IE, Mask, RHS); if (RHS == 0) RHS = UndefValue::get(LHS->getType()); @@ -443,20 +443,21 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { } // Remap any references to RHS to use LHS. - std::vector Elts; + SmallVector Elts; for (unsigned i = 0, e = LHSWidth; i != VWidth; ++i) { - if (Mask[i] < 0) + if (Mask[i] < 0) { Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); - else { - if ((Mask[i] >= (int)e && isa(RHS)) || - (Mask[i] < (int)e && isa(LHS))) { - Mask[i] = -1; // Turn into undef. - Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); - } else { - Mask[i] = Mask[i] % e; // Force to LHS. - Elts.push_back(ConstantInt::get(Type::getInt32Ty(SVI.getContext()), - Mask[i])); - } + continue; + } + + if ((Mask[i] >= (int)e && isa(RHS)) || + (Mask[i] < (int)e && isa(LHS))) { + Mask[i] = -1; // Turn into undef. + Elts.push_back(UndefValue::get(Type::getInt32Ty(SVI.getContext()))); + } else { + Mask[i] = Mask[i] % e; // Force to LHS. + Elts.push_back(ConstantInt::get(Type::getInt32Ty(SVI.getContext()), + Mask[i])); } } SVI.setOperand(0, SVI.getOperand(1)); diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 86e491b571f..64ed817e75c 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -495,8 +495,10 @@ Value *InstCombiner::dyn_castNegVal(Value *V) const { if (ConstantInt *C = dyn_cast(V)) return ConstantExpr::getNeg(C); - if (ConstantVector *C = dyn_cast(V)) - if (C->getType()->getElementType()->isIntegerTy()) + if (Constant *C = dyn_cast(V)) + // FIXME: Remove ConstantVector + if ((isa(C) || isa(C)) && + C->getType()->getVectorElementType()->isIntegerTy()) return ConstantExpr::getNeg(C); return 0; @@ -514,8 +516,10 @@ Value *InstCombiner::dyn_castFNegVal(Value *V) const { if (ConstantFP *C = dyn_cast(V)) return ConstantExpr::getFNeg(C); - if (ConstantVector *C = dyn_cast(V)) - if (C->getType()->getElementType()->isFloatingPointTy()) + if (Constant *C = dyn_cast(V)) + // FIXME: Remove ConstantVector + if ((isa(C) || isa(C)) && + C->getType()->getVectorElementType()->isFloatingPointTy()) return ConstantExpr::getFNeg(C); return 0; diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index f1b97dfce13..36bd4aba4b1 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -547,18 +547,17 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, 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 (ConstantVector *CV = dyn_cast(V)) - if (DestTy->isVectorTy() && - cast(DestTy)->getNumElements() == - CV->getType()->getNumElements()) { - std::vector res; - VectorType *DestVecTy = cast(DestTy); - 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(res); - } + if ((isa(V) || isa(V)) && + DestTy->isVectorTy() && + DestTy->getVectorNumElements() == V->getType()->getVectorNumElements()) { + SmallVector res; + VectorType *DestVecTy = cast(DestTy); + Type *DstEltTy = DestVecTy->getElementType(); + for (unsigned i = 0, e = V->getType()->getVectorNumElements(); i != e; ++i) + res.push_back(ConstantExpr::getCast(opc, + V->getAggregateElement(i), DstEltTy)); + return ConstantVector::get(res); + } // We actually have to do a cast now. Perform the cast according to the // opcode specified. @@ -694,7 +693,7 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, if (Cond->isNullValue()) return V2; if (Cond->isAllOnesValue()) return V1; - // FIXME: CDV Condition. + // FIXME: Remove ConstantVector // If the condition is a vector constant, fold the result elementwise. if (ConstantVector *CondV = dyn_cast(Cond)) { SmallVector Result; @@ -711,6 +710,20 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, if (Result.size() == V1->getType()->getVectorNumElements()) return ConstantVector::get(Result); } + if (ConstantDataVector *CondV = dyn_cast(Cond)) { + SmallVector Result; + for (unsigned i = 0, e = V1->getType()->getVectorNumElements(); i != e;++i){ + uint64_t Cond = CondV->getElementAsInteger(i); + + Constant *Res = (Cond ? V2 : V1)->getAggregateElement(i); + if (Res == 0) break; + Result.push_back(Res); + } + + // If we were able to build the vector, return it. + if (Result.size() == V1->getType()->getVectorNumElements()) + return ConstantVector::get(Result); + } if (isa(Cond)) { @@ -738,22 +751,19 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx) { if (isa(Val)) // ee(undef, x) -> undef - return UndefValue::get(cast(Val->getType())->getElementType()); + return UndefValue::get(Val->getType()->getVectorElementType()); if (Val->isNullValue()) // ee(zero, x) -> zero - return Constant::getNullValue( - cast(Val->getType())->getElementType()); - - if (ConstantVector *CVal = dyn_cast(Val)) { - if (ConstantInt *CIdx = dyn_cast(Idx)) { - uint64_t Index = CIdx->getZExtValue(); - if (Index >= CVal->getNumOperands()) - // ee({w,x,y,z}, wrong_value) -> undef - return UndefValue::get(cast(Val->getType())->getElementType()); - return CVal->getOperand(CIdx->getZExtValue()); - } else if (isa(Idx)) { - // ee({w,x,y,z}, undef) -> undef - return UndefValue::get(cast(Val->getType())->getElementType()); - } + return Constant::getNullValue(Val->getType()->getVectorElementType()); + // ee({w,x,y,z}, undef) -> undef + if (isa(Idx)) + return UndefValue::get(Val->getType()->getVectorElementType()); + + if (ConstantInt *CIdx = dyn_cast(Idx)) { + uint64_t Index = CIdx->getZExtValue(); + // ee({w,x,y,z}, wrong_value) -> undef + if (Index >= Val->getType()->getVectorNumElements()) + return UndefValue::get(Val->getType()->getVectorElementType()); + return Val->getAggregateElement(Index); } return 0; } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index d12acb524e5..282bfbc934f 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -441,12 +441,12 @@ Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) { return C; } -ConstantInt* ConstantInt::get(IntegerType* Ty, uint64_t V, +ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool isSigned) { return get(Ty->getContext(), APInt(Ty->getBitWidth(), V, isSigned)); } -ConstantInt* ConstantInt::getSigned(IntegerType* Ty, int64_t V) { +ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) { return get(Ty, V, true); } @@ -454,7 +454,7 @@ Constant *ConstantInt::getSigned(Type *Ty, int64_t V) { return get(Ty, V, true); } -Constant *ConstantInt::get(Type* Ty, const APInt& V) { +Constant *ConstantInt::get(Type *Ty, const APInt& V) { ConstantInt *C = get(Ty->getContext(), V); assert(C->getType() == Ty->getScalarType() && "ConstantInt type doesn't match the type implied by its value!"); @@ -466,7 +466,7 @@ Constant *ConstantInt::get(Type* Ty, const APInt& V) { return C; } -ConstantInt* ConstantInt::get(IntegerType* Ty, StringRef Str, +ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str, uint8_t radix) { return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix)); } @@ -496,7 +496,7 @@ void ConstantFP::anchor() { } /// 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. -Constant *ConstantFP::get(Type* Ty, double V) { +Constant *ConstantFP::get(Type *Ty, double V) { LLVMContext &Context = Ty->getContext(); APFloat FV(V); @@ -513,7 +513,7 @@ Constant *ConstantFP::get(Type* Ty, double V) { } -Constant *ConstantFP::get(Type* Ty, StringRef Str) { +Constant *ConstantFP::get(Type *Ty, StringRef Str) { LLVMContext &Context = Ty->getContext(); APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str); diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index a0fb91aada1..301791dd0be 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1932,10 +1932,8 @@ BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, // isConstantAllOnes - Helper function for several functions below static inline bool isConstantAllOnes(const Value *V) { - if (const ConstantInt *CI = dyn_cast(V)) - return CI->isAllOnesValue(); - if (const ConstantVector *CV = dyn_cast(V)) - return CV->isAllOnesValue(); + if (const Constant *C = dyn_cast(V)) + return C->isAllOnesValue(); return false; } -- 2.34.1