X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantFold.cpp;h=ff4d897e54a8b945d1d49ff959a424f49452b943;hb=b5bd026a756d8650f2a94607c9b1dc34cf1c024a;hp=93cfccf1f5e672f7f06ecf02e9a4ef392de2f8bf;hpb=8373d38afddec4ade17f72088cb5eeb229e87238;p=oota-llvm.git diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 93cfccf1f5e..ff4d897e54a 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -126,6 +126,7 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) { if (const VectorType *SrcTy = dyn_cast(V->getType())) { assert(DestPTy->getBitWidth() == SrcTy->getBitWidth() && "Not cast between same sized vectors!"); + SrcTy = NULL; // First, check for null. Undef is already handled. if (isa(V)) return Constant::getNullValue(DestTy); @@ -133,6 +134,12 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) { if (ConstantVector *CV = dyn_cast(V)) return BitCastConstantVector(CV, DestPTy); } + + // Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts + // This allows for other simplifications (although some of them + // can only be handled by Analysis/ConstantFolding.cpp). + if (isa(V) || isa(V)) + return ConstantExpr::getBitCast(ConstantVector::get(&V, 1), DestPTy); } // Finally, implement bitcast folding now. The code below doesn't handle @@ -146,26 +153,20 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) { // Integral -> Integral. This is a no-op because the bit widths must // be the same. Consequently, we just fold to V. return V; - - if (DestTy->isFloatingPoint()) { - assert((DestTy == Type::DoubleTy || DestTy == Type::FloatTy) && - "Unknown FP type!"); - return ConstantFP::get(APFloat(CI->getValue())); - } + + if (DestTy->isFloatingPoint()) + return ConstantFP::get(APFloat(CI->getValue(), + DestTy != Type::PPC_FP128Ty)); + // Otherwise, can't fold this (vector?) return 0; } - + // Handle ConstantFP input. - if (const ConstantFP *FP = dyn_cast(V)) { + if (const ConstantFP *FP = dyn_cast(V)) // FP -> Integral. - if (DestTy == Type::Int32Ty) { - return ConstantInt::get(FP->getValueAPF().convertToAPInt()); - } else { - assert(DestTy == Type::Int64Ty && "only support f32/f64 for now!"); - return ConstantInt::get(FP->getValueAPF().convertToAPInt()); - } - } + return ConstantInt::get(FP->getValueAPF().bitcastToAPInt()); + return 0; } @@ -213,13 +214,14 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, case Instruction::FPTrunc: case Instruction::FPExt: if (const ConstantFP *FPC = dyn_cast(V)) { + bool ignored; APFloat Val = FPC->getValueAPF(); Val.convert(DestTy == Type::FloatTy ? APFloat::IEEEsingle : DestTy == Type::DoubleTy ? APFloat::IEEEdouble : DestTy == Type::X86_FP80Ty ? APFloat::x87DoubleExtended : DestTy == Type::FP128Ty ? APFloat::IEEEquad : APFloat::Bogus, - APFloat::rmNearestTiesToEven); + APFloat::rmNearestTiesToEven, &ignored); return ConstantFP::get(Val); } return 0; // Can't fold. @@ -227,10 +229,11 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, case Instruction::FPToSI: if (const ConstantFP *FPC = dyn_cast(V)) { const APFloat &V = FPC->getValueAPF(); + bool ignored; uint64_t x[2]; uint32_t DestBitWidth = cast(DestTy)->getBitWidth(); (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, - APFloat::rmTowardZero); + APFloat::rmTowardZero, &ignored); APInt Val(DestBitWidth, 2, x); return ConstantInt::get(Val); } @@ -415,24 +418,25 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, const Constant *Mask) { // Undefined shuffle mask -> undefined value. if (isa(Mask)) return UndefValue::get(V1->getType()); - - unsigned NumElts = cast(V1->getType())->getNumElements(); + + unsigned MaskNumElts = cast(Mask->getType())->getNumElements(); + unsigned SrcNumElts = cast(V1->getType())->getNumElements(); const Type *EltTy = cast(V1->getType())->getElementType(); - + // Loop over the shuffle mask, evaluating each element. SmallVector Result; - for (unsigned i = 0; i != NumElts; ++i) { + for (unsigned i = 0; i != MaskNumElts; ++i) { Constant *InElt = GetVectorElement(Mask, i); if (InElt == 0) return 0; - + if (isa(InElt)) InElt = UndefValue::get(EltTy); else if (ConstantInt *CI = dyn_cast(InElt)) { unsigned Elt = CI->getZExtValue(); - if (Elt >= NumElts*2) + if (Elt >= SrcNumElts*2) InElt = UndefValue::get(EltTy); - else if (Elt >= NumElts) - InElt = GetVectorElement(V2, Elt-NumElts); + else if (Elt >= SrcNumElts) + InElt = GetVectorElement(V2, Elt - SrcNumElts); else InElt = GetVectorElement(V1, Elt); if (InElt == 0) return 0; @@ -442,7 +446,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, } Result.push_back(InElt); } - + return ConstantVector::get(&Result[0], Result.size()); } @@ -645,11 +649,15 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, case Instruction::SDiv: if (CI2->equalsInt(1)) return const_cast(C1); // X / 1 == X + if (CI2->equalsInt(0)) + return UndefValue::get(CI2->getType()); // X / 0 == undef break; case Instruction::URem: case Instruction::SRem: if (CI2->equalsInt(1)) return Constant::getNullValue(CI2->getType()); // X % 1 == 0 + if (CI2->equalsInt(0)) + return UndefValue::get(CI2->getType()); // X % 0 == undef break; case Instruction::And: if (CI2->isZero()) return const_cast(C2); // X & 0 == 0 @@ -723,24 +731,20 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, case Instruction::Mul: return ConstantInt::get(C1V * C2V); case Instruction::UDiv: - if (CI2->isNullValue()) - return 0; // X / 0 -> can't fold + assert(!CI2->isNullValue() && "Div by zero handled above"); return ConstantInt::get(C1V.udiv(C2V)); case Instruction::SDiv: - if (CI2->isNullValue()) - return 0; // X / 0 -> can't fold + assert(!CI2->isNullValue() && "Div by zero handled above"); if (C2V.isAllOnesValue() && C1V.isMinSignedValue()) - return 0; // MIN_INT / -1 -> overflow + return UndefValue::get(CI1->getType()); // MIN_INT / -1 -> undef return ConstantInt::get(C1V.sdiv(C2V)); case Instruction::URem: - if (C2->isNullValue()) - return 0; // X / 0 -> can't fold + assert(!CI2->isNullValue() && "Div by zero handled above"); return ConstantInt::get(C1V.urem(C2V)); - case Instruction::SRem: - if (CI2->isNullValue()) - return 0; // X % 0 -> can't fold + case Instruction::SRem: + assert(!CI2->isNullValue() && "Div by zero handled above"); if (C2V.isAllOnesValue() && C1V.isMinSignedValue()) - return 0; // MIN_INT % -1 -> overflow + return UndefValue::get(CI1->getType()); // MIN_INT % -1 -> undef return ConstantInt::get(C1V.srem(C2V)); case Instruction::And: return ConstantInt::get(C1V & C2V); @@ -792,16 +796,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven); return ConstantFP::get(C3V); case Instruction::FRem: - if (C2V.isZero()) { - // IEEE 754, Section 7.1, #5 - if (CFP1->getType() == Type::DoubleTy) - return ConstantFP::get(APFloat(std::numeric_limits:: - quiet_NaN())); - if (CFP1->getType() == Type::FloatTy) - return ConstantFP::get(APFloat(std::numeric_limits:: - quiet_NaN())); - break; - } (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven); return ConstantFP::get(C3V); }