X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantFold.cpp;h=ff4d897e54a8b945d1d49ff959a424f49452b943;hb=2625f9b2e4388a957286063f6c7fe5406fd0ca7a;hp=5e5bbeaae1ffae1105a59732eb833b6dc8088511;hpb=f286f6fd93d569befe6e77c94a947e6e04e95685;p=oota-llvm.git diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 5e5bbeaae1f..ff4d897e54a 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -36,81 +36,31 @@ using namespace llvm; // ConstantFold*Instruction Implementations //===----------------------------------------------------------------------===// -/// CastConstantVector - Convert the specified ConstantVector node to the +/// BitCastConstantVector - Convert the specified ConstantVector node to the /// specified vector type. At this point, we know that the elements of the /// input vector constant are all simple integer or FP values. -static Constant *CastConstantVector(ConstantVector *CV, - const VectorType *DstTy) { - unsigned SrcNumElts = CV->getType()->getNumElements(); - unsigned DstNumElts = DstTy->getNumElements(); - const Type *SrcEltTy = CV->getType()->getElementType(); - const Type *DstEltTy = DstTy->getElementType(); +static Constant *BitCastConstantVector(ConstantVector *CV, + const VectorType *DstTy) { + // If this cast changes element count then we can't handle it here: + // doing so requires endianness information. This should be handled by + // Analysis/ConstantFolding.cpp + unsigned NumElts = DstTy->getNumElements(); + if (NumElts != CV->getNumOperands()) + return 0; - // If both vectors have the same number of elements (thus, the elements - // are the same size), perform the conversion now. - if (SrcNumElts == DstNumElts) { - std::vector Result; - - // If the src and dest elements are both integers, or both floats, we can - // just BitCast each element because the elements are the same size. - if ((SrcEltTy->isInteger() && DstEltTy->isInteger()) || - (SrcEltTy->isFloatingPoint() && DstEltTy->isFloatingPoint())) { - for (unsigned i = 0; i != SrcNumElts; ++i) - Result.push_back( - ConstantExpr::getBitCast(CV->getOperand(i), DstEltTy)); - return ConstantVector::get(Result); - } - - // If this is an int-to-fp cast .. - if (SrcEltTy->isInteger()) { - // Ensure that it is int-to-fp cast - assert(DstEltTy->isFloatingPoint()); - if (DstEltTy->getTypeID() == Type::DoubleTyID) { - for (unsigned i = 0; i != SrcNumElts; ++i) { - ConstantInt *CI = cast(CV->getOperand(i)); - double V = CI->getValue().bitsToDouble(); - Result.push_back(ConstantFP::get(Type::DoubleTy, APFloat(V))); - } - return ConstantVector::get(Result); - } - assert(DstEltTy == Type::FloatTy && "Unknown fp type!"); - for (unsigned i = 0; i != SrcNumElts; ++i) { - ConstantInt *CI = cast(CV->getOperand(i)); - float V = CI->getValue().bitsToFloat(); - Result.push_back(ConstantFP::get(Type::FloatTy, APFloat(V))); - } - return ConstantVector::get(Result); - } - - // Otherwise, this is an fp-to-int cast. - assert(SrcEltTy->isFloatingPoint() && DstEltTy->isInteger()); - - if (SrcEltTy->getTypeID() == Type::DoubleTyID) { - for (unsigned i = 0; i != SrcNumElts; ++i) { - uint64_t V = cast(CV->getOperand(i))-> - getValueAPF().convertToAPInt().getZExtValue(); - Constant *C = ConstantInt::get(Type::Int64Ty, V); - Result.push_back(ConstantExpr::getBitCast(C, DstEltTy )); - } - return ConstantVector::get(Result); - } - - assert(SrcEltTy->getTypeID() == Type::FloatTyID); - for (unsigned i = 0; i != SrcNumElts; ++i) { - uint32_t V = (uint32_t)cast(CV->getOperand(i))-> - getValueAPF().convertToAPInt().getZExtValue(); - Constant *C = ConstantInt::get(Type::Int32Ty, V); - Result.push_back(ConstantExpr::getBitCast(C, DstEltTy)); - } - return ConstantVector::get(Result); + // Check to verify that all elements of the input are simple. + for (unsigned i = 0; i != NumElts; ++i) { + if (!isa(CV->getOperand(i)) && + !isa(CV->getOperand(i))) + return 0; } - - // Otherwise, this is a cast that changes element count and size. Handle - // casts which shrink the elements here. - - // FIXME: We need to know endianness to do this! - - return 0; + + // Bitcast each element now. + std::vector Result; + const Type *DstEltTy = DstTy->getElementType(); + for (unsigned i = 0; i != NumElts; ++i) + Result.push_back(ConstantExpr::getBitCast(CV->getOperand(i), DstEltTy)); + return ConstantVector::get(Result); } /// This function determines which opcode to use to fold two constant cast @@ -138,14 +88,97 @@ foldConstantCastPair( Type::Int64Ty); } -Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, - const Type *DestTy) { +static Constant *FoldBitCast(Constant *V, const Type *DestTy) { const Type *SrcTy = V->getType(); + if (SrcTy == DestTy) + return V; // no-op cast + + // Check to see if we are casting a pointer to an aggregate to a pointer to + // the first element. If so, return the appropriate GEP instruction. + if (const PointerType *PTy = dyn_cast(V->getType())) + if (const PointerType *DPTy = dyn_cast(DestTy)) + if (PTy->getAddressSpace() == DPTy->getAddressSpace()) { + SmallVector IdxList; + IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); + const Type *ElTy = PTy->getElementType(); + while (ElTy != DPTy->getElementType()) { + if (const StructType *STy = dyn_cast(ElTy)) { + if (STy->getNumElements() == 0) break; + ElTy = STy->getElementType(0); + IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); + } else if (const SequentialType *STy = + dyn_cast(ElTy)) { + if (isa(ElTy)) break; // Can't index into pointers! + ElTy = STy->getElementType(); + IdxList.push_back(IdxList[0]); + } else { + break; + } + } + + if (ElTy == DPTy->getElementType()) + return ConstantExpr::getGetElementPtr(V, &IdxList[0], IdxList.size()); + } + + // Handle casts from one vector constant to another. We know that the src + // and dest type have the same size (otherwise its an illegal cast). + if (const VectorType *DestPTy = dyn_cast(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); + + 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 + // bitcast right. + if (isa(V)) // ptr->ptr cast. + return ConstantPointerNull::get(cast(DestTy)); + + // Handle integral constant input. + if (const ConstantInt *CI = dyn_cast(V)) { + if (DestTy->isInteger()) + // 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()) + 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)) + // FP -> Integral. + return ConstantInt::get(FP->getValueAPF().bitcastToAPInt()); + return 0; +} + + +Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, + const Type *DestTy) { if (isa(V)) { // zext(undef) = 0, because the top bits will be zero. // sext(undef) = 0, because the top bits will all be the same. - if (opc == Instruction::ZExt || opc == Instruction::SExt) + // [us]itofp(undef) = 0, because the result value is bounded. + if (opc == Instruction::ZExt || opc == Instruction::SExt || + opc == Instruction::UIToFP || opc == Instruction::SIToFP) return Constant::getNullValue(DestTy); return UndefValue::get(DestTy); } @@ -181,24 +214,26 @@ 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); - return ConstantFP::get(DestTy, Val); + APFloat::rmNearestTiesToEven, &ignored); + return ConstantFP::get(Val); } return 0; // Can't fold. case Instruction::FPToUI: 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); } @@ -207,8 +242,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, const VectorType *DestVecTy = cast(DestTy); const Type *DstEltTy = DestVecTy->getElementType(); for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) - res.push_back(ConstantFoldCastInstruction(opc, V->getOperand(i), - DstEltTy)); + res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy)); return ConstantVector::get(DestVecTy, res); } return 0; // Can't fold. @@ -225,21 +259,19 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, if (const ConstantInt *CI = dyn_cast(V)) { APInt api = CI->getValue(); const uint64_t zero[] = {0, 0}; - uint32_t BitWidth = cast(SrcTy)->getBitWidth(); APFloat apf = APFloat(APInt(DestTy->getPrimitiveSizeInBits(), 2, zero)); - (void)apf.convertFromZeroExtendedInteger(api.getRawData(), BitWidth, - opc==Instruction::SIToFP, - APFloat::rmNearestTiesToEven); - return ConstantFP::get(DestTy, apf); + (void)apf.convertFromAPInt(api, + opc==Instruction::SIToFP, + 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(ConstantFoldCastInstruction(opc, V->getOperand(i), - DstEltTy)); + res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy)); return ConstantVector::get(DestVecTy, res); } return 0; @@ -268,100 +300,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, } return 0; case Instruction::BitCast: - if (SrcTy == DestTy) - return (Constant*)V; // no-op cast - - // Check to see if we are casting a pointer to an aggregate to a pointer to - // the first element. If so, return the appropriate GEP instruction. - if (const PointerType *PTy = dyn_cast(V->getType())) - if (const PointerType *DPTy = dyn_cast(DestTy)) { - SmallVector IdxList; - IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); - const Type *ElTy = PTy->getElementType(); - while (ElTy != DPTy->getElementType()) { - if (const StructType *STy = dyn_cast(ElTy)) { - if (STy->getNumElements() == 0) break; - ElTy = STy->getElementType(0); - IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); - } else if (const SequentialType *STy = - dyn_cast(ElTy)) { - if (isa(ElTy)) break; // Can't index into pointers! - ElTy = STy->getElementType(); - IdxList.push_back(IdxList[0]); - } else { - break; - } - } - - if (ElTy == DPTy->getElementType()) - return ConstantExpr::getGetElementPtr( - const_cast(V), &IdxList[0], IdxList.size()); - } - - // Handle casts from one vector constant to another. We know that the src - // and dest type have the same size (otherwise its an illegal cast). - if (const VectorType *DestPTy = dyn_cast(DestTy)) { - if (const VectorType *SrcTy = dyn_cast(V->getType())) { - assert(DestPTy->getBitWidth() == SrcTy->getBitWidth() && - "Not cast between same sized vectors!"); - // First, check for null and undef - if (isa(V)) - return Constant::getNullValue(DestTy); - if (isa(V)) - return UndefValue::get(DestTy); - - if (const ConstantVector *CV = dyn_cast(V)) { - // This is a cast from a ConstantVector of one type to a - // ConstantVector of another type. Check to see if all elements of - // the input are simple. - bool AllSimpleConstants = true; - for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) { - if (!isa(CV->getOperand(i)) && - !isa(CV->getOperand(i))) { - AllSimpleConstants = false; - break; - } - } - - // If all of the elements are simple constants, we can fold this. - if (AllSimpleConstants) - return CastConstantVector(const_cast(CV), DestPTy); - } - } - } - - // Finally, implement bitcast folding now. The code below doesn't handle - // bitcast right. - if (isa(V)) // ptr->ptr cast. - return ConstantPointerNull::get(cast(DestTy)); - - // Handle integral constant input. - if (const ConstantInt *CI = dyn_cast(V)) { - if (DestTy->isInteger()) - // Integral -> Integral. This is a no-op because the bit widths must - // be the same. Consequently, we just fold to V. - return const_cast(V); - - if (DestTy->isFloatingPoint()) { - assert((DestTy == Type::DoubleTy || DestTy == Type::FloatTy) && - "Unknown FP type!"); - return ConstantFP::get(DestTy, APFloat(CI->getValue())); - } - // Otherwise, can't fold this (vector?) - return 0; - } - - // Handle ConstantFP input. - 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 0; + return FoldBitCast(const_cast(V), DestTy); default: assert(!"Invalid CE CastInst opcode"); break; @@ -394,10 +333,10 @@ Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val, if (const ConstantVector *CVal = dyn_cast(Val)) { if (const ConstantInt *CIdx = dyn_cast(Idx)) { - return const_cast(CVal->getOperand(CIdx->getZExtValue())); + return CVal->getOperand(CIdx->getZExtValue()); } else if (isa(Idx)) { // ee({w,x,y,z}, undef) -> w (an arbitrary value). - return const_cast(CVal->getOperand(0)); + return CVal->getOperand(0); } } return 0; @@ -456,13 +395,167 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, } return ConstantVector::get(Ops); } + + return 0; +} + +/// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef +/// return the specified element value. Otherwise return null. +static Constant *GetVectorElement(const Constant *C, unsigned EltNo) { + if (const ConstantVector *CV = dyn_cast(C)) + return CV->getOperand(EltNo); + + const Type *EltTy = cast(C->getType())->getElementType(); + if (isa(C)) + return Constant::getNullValue(EltTy); + if (isa(C)) + return UndefValue::get(EltTy); return 0; } Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, const Constant *V2, const Constant *Mask) { - // TODO: + // Undefined shuffle mask -> undefined value. + if (isa(Mask)) return UndefValue::get(V1->getType()); + + 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 != 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 >= SrcNumElts*2) + InElt = UndefValue::get(EltTy); + else if (Elt >= SrcNumElts) + InElt = GetVectorElement(V2, Elt - SrcNumElts); + else + InElt = GetVectorElement(V1, Elt); + if (InElt == 0) return 0; + } else { + // Unknown value. + return 0; + } + Result.push_back(InElt); + } + + return ConstantVector::get(&Result[0], Result.size()); +} + +Constant *llvm::ConstantFoldExtractValueInstruction(const Constant *Agg, + const unsigned *Idxs, + unsigned NumIdx) { + // Base case: no indices, so return the entire value. + if (NumIdx == 0) + return const_cast(Agg); + + if (isa(Agg)) // ev(undef, x) -> undef + return UndefValue::get(ExtractValueInst::getIndexedType(Agg->getType(), + Idxs, + Idxs + NumIdx)); + + if (isa(Agg)) // ev(0, x) -> 0 + return + Constant::getNullValue(ExtractValueInst::getIndexedType(Agg->getType(), + Idxs, + Idxs + NumIdx)); + + // Otherwise recurse. + return ConstantFoldExtractValueInstruction(Agg->getOperand(*Idxs), + Idxs+1, NumIdx-1); +} + +Constant *llvm::ConstantFoldInsertValueInstruction(const Constant *Agg, + const Constant *Val, + const unsigned *Idxs, + unsigned NumIdx) { + // Base case: no indices, so replace the entire value. + if (NumIdx == 0) + return const_cast(Val); + + if (isa(Agg)) { + // Insertion of constant into aggregate undef + // Optimize away insertion of undef + if (isa(Val)) + return const_cast(Agg); + // Otherwise break the aggregate undef into multiple undefs and do + // the insertion + const CompositeType *AggTy = cast(Agg->getType()); + unsigned numOps; + if (const ArrayType *AR = dyn_cast(AggTy)) + numOps = AR->getNumElements(); + else + numOps = cast(AggTy)->getNumElements(); + std::vector Ops(numOps); + for (unsigned i = 0; i < numOps; ++i) { + const Type *MemberTy = AggTy->getTypeAtIndex(i); + const Constant *Op = + (*Idxs == i) ? + ConstantFoldInsertValueInstruction(UndefValue::get(MemberTy), + Val, Idxs+1, NumIdx-1) : + UndefValue::get(MemberTy); + Ops[i] = const_cast(Op); + } + if (isa(AggTy)) + return ConstantStruct::get(Ops); + else + return ConstantArray::get(cast(AggTy), Ops); + } + if (isa(Agg)) { + // Insertion of constant into aggregate zero + // Optimize away insertion of zero + if (Val->isNullValue()) + return const_cast(Agg); + // Otherwise break the aggregate zero into multiple zeros and do + // the insertion + const CompositeType *AggTy = cast(Agg->getType()); + unsigned numOps; + if (const ArrayType *AR = dyn_cast(AggTy)) + numOps = AR->getNumElements(); + else + numOps = cast(AggTy)->getNumElements(); + std::vector Ops(numOps); + for (unsigned i = 0; i < numOps; ++i) { + const Type *MemberTy = AggTy->getTypeAtIndex(i); + const Constant *Op = + (*Idxs == i) ? + ConstantFoldInsertValueInstruction(Constant::getNullValue(MemberTy), + Val, Idxs+1, NumIdx-1) : + Constant::getNullValue(MemberTy); + Ops[i] = const_cast(Op); + } + if (isa(AggTy)) + return ConstantStruct::get(Ops); + else + return ConstantArray::get(cast(AggTy), Ops); + } + if (isa(Agg) || isa(Agg)) { + // Insertion of constant into aggregate constant + std::vector Ops(Agg->getNumOperands()); + for (unsigned i = 0; i < Agg->getNumOperands(); ++i) { + const Constant *Op = + (*Idxs == i) ? + ConstantFoldInsertValueInstruction(Agg->getOperand(i), + Val, Idxs+1, NumIdx-1) : + Agg->getOperand(i); + Ops[i] = const_cast(Op); + } + Constant *C; + if (isa(Agg->getType())) + C = ConstantStruct::get(Ops); + else + C = ConstantArray::get(cast(Agg->getType()), Ops); + return C; + } + return 0; } @@ -495,9 +588,14 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, // Handle UndefValue up front if (isa(C1) || isa(C2)) { switch (Opcode) { + case Instruction::Xor: + if (isa(C1) && isa(C2)) + // Handle undef ^ undef -> 0 special case. This is a common + // idiom (misuse). + return Constant::getNullValue(C1->getType()); + // Fallthrough case Instruction::Add: case Instruction::Sub: - case Instruction::Xor: return UndefValue::get(C1->getType()); case Instruction::Mul: case Instruction::And: @@ -533,115 +631,96 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } } - if (const ConstantExpr *CE1 = dyn_cast(C1)) { - if (isa(C2)) { - // There are many possible foldings we could do here. We should probably - // at least fold add of a pointer with an integer into the appropriate - // getelementptr. This will improve alias analysis a bit. - } else { - // Just implement a couple of simple identities. - switch (Opcode) { - case Instruction::Add: - if (C2->isNullValue()) return const_cast(C1); // X + 0 == X - break; - case Instruction::Sub: - if (C2->isNullValue()) return const_cast(C1); // X - 0 == X - break; - case Instruction::Mul: - if (C2->isNullValue()) return const_cast(C2); // X * 0 == 0 - if (const ConstantInt *CI = dyn_cast(C2)) - if (CI->equalsInt(1)) - return const_cast(C1); // X * 1 == X - break; - case Instruction::UDiv: - case Instruction::SDiv: - if (const ConstantInt *CI = dyn_cast(C2)) - if (CI->equalsInt(1)) - return const_cast(C1); // X / 1 == X - break; - case Instruction::URem: - case Instruction::SRem: - if (const ConstantInt *CI = dyn_cast(C2)) - if (CI->equalsInt(1)) - return Constant::getNullValue(CI->getType()); // X % 1 == 0 - break; - case Instruction::And: - if (const ConstantInt *CI = dyn_cast(C2)) { - if (CI->isZero()) return const_cast(C2); // X & 0 == 0 - if (CI->isAllOnesValue()) - return const_cast(C1); // X & -1 == X - - // (zext i32 to i64) & 4294967295 -> (zext i32 to i64) - if (CE1->getOpcode() == Instruction::ZExt) { - APInt PossiblySetBits - = cast(CE1->getOperand(0)->getType())->getMask(); - PossiblySetBits.zext(C1->getType()->getPrimitiveSizeInBits()); - if ((PossiblySetBits & CI->getValue()) == PossiblySetBits) - return const_cast(C1); - } - } - if (CE1->isCast() && isa(CE1->getOperand(0))) { - GlobalValue *CPR = cast(CE1->getOperand(0)); - - // Functions are at least 4-byte aligned. If and'ing the address of a - // function with a constant < 4, fold it to zero. - if (const ConstantInt *CI = dyn_cast(C2)) - if (CI->getValue().ult(APInt(CI->getType()->getBitWidth(),4)) && - isa(CPR)) - return Constant::getNullValue(CI->getType()); - } - break; - case Instruction::Or: - if (C2->isNullValue()) return const_cast(C1); // X | 0 == X - if (const ConstantInt *CI = dyn_cast(C2)) - if (CI->isAllOnesValue()) - return const_cast(C2); // X | -1 == -1 - break; - case Instruction::Xor: - if (C2->isNullValue()) return const_cast(C1); // X ^ 0 == X - break; - case Instruction::AShr: - // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2 - if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero. - return ConstantExpr::getLShr(const_cast(C1), - const_cast(C2)); - break; - } - } - } else if (isa(C2)) { - // If C2 is a constant expr and C1 isn't, flop them around and fold the - // other way if possible. + // Handle simplifications of the RHS when a constant int. + if (const ConstantInt *CI2 = dyn_cast(C2)) { switch (Opcode) { case Instruction::Add: + if (CI2->equalsInt(0)) return const_cast(C1); // X + 0 == X + break; + case Instruction::Sub: + if (CI2->equalsInt(0)) return const_cast(C1); // X - 0 == X + break; case Instruction::Mul: + if (CI2->equalsInt(0)) return const_cast(C2); // X * 0 == 0 + if (CI2->equalsInt(1)) + return const_cast(C1); // X * 1 == X + break; + case Instruction::UDiv: + 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 + if (CI2->isAllOnesValue()) + return const_cast(C1); // X & -1 == X + + if (const ConstantExpr *CE1 = dyn_cast(C1)) { + // (zext i32 to i64) & 4294967295 -> (zext i32 to i64) + if (CE1->getOpcode() == Instruction::ZExt) { + unsigned DstWidth = CI2->getType()->getBitWidth(); + unsigned SrcWidth = + CE1->getOperand(0)->getType()->getPrimitiveSizeInBits(); + APInt PossiblySetBits(APInt::getLowBitsSet(DstWidth, SrcWidth)); + if ((PossiblySetBits & CI2->getValue()) == PossiblySetBits) + return const_cast(C1); + } + + // If and'ing the address of a global with a constant, fold it. + if (CE1->getOpcode() == Instruction::PtrToInt && + isa(CE1->getOperand(0))) { + GlobalValue *GV = cast(CE1->getOperand(0)); + + // Functions are at least 4-byte aligned. + unsigned GVAlign = GV->getAlignment(); + if (isa(GV)) + GVAlign = std::max(GVAlign, 4U); + + if (GVAlign > 1) { + unsigned DstWidth = CI2->getType()->getBitWidth(); + unsigned SrcWidth = std::min(DstWidth, Log2_32(GVAlign)); + APInt BitsNotSet(APInt::getLowBitsSet(DstWidth, SrcWidth)); + + // If checking bits we know are clear, return zero. + if ((CI2->getValue() & BitsNotSet) == CI2->getValue()) + return Constant::getNullValue(CI2->getType()); + } + } + } + break; case Instruction::Or: + if (CI2->equalsInt(0)) return const_cast(C1); // X | 0 == X + if (CI2->isAllOnesValue()) + return const_cast(C2); // X | -1 == -1 + break; case Instruction::Xor: - // No change of opcode required. - return ConstantFoldBinaryInstruction(Opcode, C2, C1); - - case Instruction::Shl: - case Instruction::LShr: + if (CI2->equalsInt(0)) return const_cast(C1); // X ^ 0 == X + break; case Instruction::AShr: - case Instruction::Sub: - case Instruction::SDiv: - case Instruction::UDiv: - case Instruction::FDiv: - case Instruction::URem: - case Instruction::SRem: - case Instruction::FRem: - default: // These instructions cannot be flopped around. - return 0; + // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2 + if (const ConstantExpr *CE1 = dyn_cast(C1)) + if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero. + return ConstantExpr::getLShr(const_cast(C1), + const_cast(C2)); + break; } } - - // At this point we know neither constant is an UndefValue nor a ConstantExpr - // so look at directly computing the value. + + // At this point we know neither constant is an UndefValue. if (const ConstantInt *CI1 = dyn_cast(C1)) { if (const ConstantInt *CI2 = dyn_cast(C2)) { using namespace APIntOps; - APInt C1V = CI1->getValue(); - APInt C2V = CI2->getValue(); + const APInt &C1V = CI1->getValue(); + const APInt &C2V = CI2->getValue(); switch (Opcode) { default: break; @@ -652,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); @@ -677,27 +752,27 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, return ConstantInt::get(C1V | C2V); case Instruction::Xor: return ConstantInt::get(C1V ^ C2V); - case Instruction::Shl: - if (uint32_t shiftAmt = C2V.getZExtValue()) - if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.shl(shiftAmt)); - else - return UndefValue::get(C1->getType()); // too big shift is undef - return const_cast(CI1); // Zero shift is identity - case Instruction::LShr: - if (uint32_t shiftAmt = C2V.getZExtValue()) - if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.lshr(shiftAmt)); - else - return UndefValue::get(C1->getType()); // too big shift is undef - return const_cast(CI1); // Zero shift is identity - case Instruction::AShr: - if (uint32_t shiftAmt = C2V.getZExtValue()) - if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.ashr(shiftAmt)); - else - return UndefValue::get(C1->getType()); // too big shift is undef - return const_cast(CI1); // Zero shift is identity + case Instruction::Shl: { + uint32_t shiftAmt = C2V.getZExtValue(); + if (shiftAmt < C1V.getBitWidth()) + return ConstantInt::get(C1V.shl(shiftAmt)); + else + return UndefValue::get(C1->getType()); // too big shift is undef + } + case Instruction::LShr: { + uint32_t shiftAmt = C2V.getZExtValue(); + if (shiftAmt < C1V.getBitWidth()) + return ConstantInt::get(C1V.lshr(shiftAmt)); + else + return UndefValue::get(C1->getType()); // too big shift is undef + } + case Instruction::AShr: { + uint32_t shiftAmt = C2V.getZExtValue(); + if (shiftAmt < C1V.getBitWidth()) + return ConstantInt::get(C1V.ashr(shiftAmt)); + else + return UndefValue::get(C1->getType()); // too big shift is undef + } } } } else if (const ConstantFP *CFP1 = dyn_cast(C1)) { @@ -705,30 +780,24 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, APFloat C1V = CFP1->getValueAPF(); APFloat C2V = CFP2->getValueAPF(); APFloat C3V = C1V; // copy for modification - bool isDouble = CFP1->getType()==Type::DoubleTy; switch (Opcode) { default: break; case Instruction::Add: (void)C3V.add(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(CFP1->getType(), C3V); + return ConstantFP::get(C3V); case Instruction::Sub: (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(CFP1->getType(), C3V); + return ConstantFP::get(C3V); case Instruction::Mul: (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(CFP1->getType(), C3V); + return ConstantFP::get(C3V); case Instruction::FDiv: (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(CFP1->getType(), C3V); + return ConstantFP::get(C3V); case Instruction::FRem: - if (C2V.isZero()) - // IEEE 754, Section 7.1, #5 - return ConstantFP::get(CFP1->getType(), isDouble ? - APFloat(std::numeric_limits::quiet_NaN()) : - APFloat(std::numeric_limits::quiet_NaN())); (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(CFP1->getType(), C3V); + return ConstantFP::get(C3V); } } } else if (const VectorType *VTy = dyn_cast(C1->getType())) { @@ -737,37 +806,68 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, if ((CP1 != NULL || isa(C1)) && (CP2 != NULL || isa(C2))) { switch (Opcode) { - default: - break; - case Instruction::Add: + default: + break; + case Instruction::Add: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAdd); - case Instruction::Sub: + case Instruction::Sub: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSub); - case Instruction::Mul: + case Instruction::Mul: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getMul); - case Instruction::UDiv: + case Instruction::UDiv: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getUDiv); - case Instruction::SDiv: + case Instruction::SDiv: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSDiv); - case Instruction::FDiv: + case Instruction::FDiv: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFDiv); - case Instruction::URem: + case Instruction::URem: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getURem); - case Instruction::SRem: + case Instruction::SRem: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSRem); - case Instruction::FRem: + case Instruction::FRem: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFRem); - case Instruction::And: + case Instruction::And: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAnd); - case Instruction::Or: + case Instruction::Or: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getOr); - case Instruction::Xor: + case Instruction::Xor: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getXor); } } } - // We don't know how to fold this + if (isa(C1)) { + // There are many possible foldings we could do here. We should probably + // at least fold add of a pointer with an integer into the appropriate + // getelementptr. This will improve alias analysis a bit. + } else if (isa(C2)) { + // If C2 is a constant expr and C1 isn't, flop them around and fold the + // other way if possible. + switch (Opcode) { + case Instruction::Add: + case Instruction::Mul: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + // No change of opcode required. + return ConstantFoldBinaryInstruction(Opcode, C2, C1); + + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + case Instruction::Sub: + case Instruction::SDiv: + case Instruction::UDiv: + case Instruction::FDiv: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: + default: // These instructions cannot be flopped around. + break; + } + } + + // We don't know how to fold this. return 0; } @@ -1101,18 +1201,20 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, // Ok, we ran out of things they have in common. If any leftovers // are non-zero then we have a difference, otherwise we are equal. for (; i < CE1->getNumOperands(); ++i) - if (!CE1->getOperand(i)->isNullValue()) + if (!CE1->getOperand(i)->isNullValue()) { if (isa(CE1->getOperand(i))) return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; else return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal. + } for (; i < CE2->getNumOperands(); ++i) - if (!CE2->getOperand(i)->isNullValue()) + if (!CE2->getOperand(i)->isNullValue()) { if (isa(CE2->getOperand(i))) return isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; else return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal. + } return ICmpInst::ICMP_EQ; } } @@ -1128,10 +1230,30 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, const Constant *C1, const Constant *C2) { - + // Fold FCMP_FALSE/FCMP_TRUE unconditionally. + if (pred == FCmpInst::FCMP_FALSE) { + if (const VectorType *VT = dyn_cast(C1->getType())) + return Constant::getNullValue(VectorType::getInteger(VT)); + else + return ConstantInt::getFalse(); + } + + if (pred == FCmpInst::FCMP_TRUE) { + if (const VectorType *VT = dyn_cast(C1->getType())) + return Constant::getAllOnesValue(VectorType::getInteger(VT)); + else + return ConstantInt::getTrue(); + } + // Handle some degenerate cases first - if (isa(C1) || isa(C2)) + if (isa(C1) || isa(C2)) { + // vicmp/vfcmp -> [vector] undef + if (const VectorType *VTy = dyn_cast(C1->getType())) + return UndefValue::get(VectorType::getInteger(VTy)); + + // icmp/fcmp -> i1 undef return UndefValue::get(Type::Int1Ty); + } // No compile-time operations on this type yet. if (C1->getType() == Type::PPC_FP128Ty) @@ -1141,20 +1263,22 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, if (C1->isNullValue()) { if (const GlobalValue *GV = dyn_cast(C2)) // Don't try to evaluate aliases. External weak GV can be null. - if (!isa(GV) && !GV->hasExternalWeakLinkage()) + if (!isa(GV) && !GV->hasExternalWeakLinkage()) { if (pred == ICmpInst::ICMP_EQ) return ConstantInt::getFalse(); else if (pred == ICmpInst::ICMP_NE) return ConstantInt::getTrue(); + } // icmp eq/ne(GV,null) -> false/true } else if (C2->isNullValue()) { if (const GlobalValue *GV = dyn_cast(C1)) // Don't try to evaluate aliases. External weak GV can be null. - if (!isa(GV) && !GV->hasExternalWeakLinkage()) + if (!isa(GV) && !GV->hasExternalWeakLinkage()) { if (pred == ICmpInst::ICMP_EQ) return ConstantInt::getFalse(); else if (pred == ICmpInst::ICMP_NE) return ConstantInt::getTrue(); + } } if (isa(C1) && isa(C2)) { @@ -1216,33 +1340,47 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan || R==APFloat::cmpEqual); } - } else if (const ConstantVector *CP1 = dyn_cast(C1)) { - if (const ConstantVector *CP2 = dyn_cast(C2)) { - if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) { - for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) { - Constant *C= ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, - const_cast(CP1->getOperand(i)), - const_cast(CP2->getOperand(i))); - if (ConstantInt *CB = dyn_cast(C)) - return CB; - } - // Otherwise, could not decide from any element pairs. - return 0; - } else if (pred == ICmpInst::ICMP_EQ) { - for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) { - Constant *C = ConstantExpr::getICmp(ICmpInst::ICMP_EQ, - const_cast(CP1->getOperand(i)), - const_cast(CP2->getOperand(i))); - if (ConstantInt *CB = dyn_cast(C)) - return CB; - } - // Otherwise, could not decide from any element pairs. - return 0; + } else if (isa(C1->getType())) { + SmallVector C1Elts, C2Elts; + C1->getVectorElements(C1Elts); + C2->getVectorElements(C2Elts); + + // If we can constant fold the comparison of each element, constant fold + // the whole vector comparison. + SmallVector ResElts; + const Type *InEltTy = C1Elts[0]->getType(); + bool isFP = InEltTy->isFloatingPoint(); + const Type *ResEltTy = InEltTy; + if (isFP) + ResEltTy = IntegerType::get(InEltTy->getPrimitiveSizeInBits()); + + for (unsigned i = 0, e = C1Elts.size(); i != e; ++i) { + // Compare the elements, producing an i1 result or constant expr. + Constant *C; + if (isFP) + C = ConstantExpr::getFCmp(pred, C1Elts[i], C2Elts[i]); + else + C = ConstantExpr::getICmp(pred, C1Elts[i], C2Elts[i]); + + // If it is a bool or undef result, convert to the dest type. + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->isZero()) + ResElts.push_back(Constant::getNullValue(ResEltTy)); + else + ResElts.push_back(Constant::getAllOnesValue(ResEltTy)); + } else if (isa(C)) { + ResElts.push_back(UndefValue::get(ResEltTy)); + } else { + break; } } + + if (ResElts.size() == C1Elts.size()) + return ConstantVector::get(&ResElts[0], ResElts.size()); } if (C1->getType()->isFloatingPoint()) { + int Result = -1; // -1 = unknown, 0 = known false, 1 = known true. switch (evaluateFCmpRelation(C1, C2)) { default: assert(0 && "Unknown relation!"); case FCmpInst::FCMP_UNO: @@ -1258,44 +1396,57 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, case FCmpInst::BAD_FCMP_PREDICATE: break; // Couldn't determine anything about these constants. case FCmpInst::FCMP_OEQ: // We know that C1 == C2 - return ConstantInt::get(Type::Int1Ty, - pred == FCmpInst::FCMP_UEQ || pred == FCmpInst::FCMP_OEQ || - pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE || - pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE); + Result = (pred == FCmpInst::FCMP_UEQ || pred == FCmpInst::FCMP_OEQ || + pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE || + pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE); + break; case FCmpInst::FCMP_OLT: // We know that C1 < C2 - return ConstantInt::get(Type::Int1Ty, - pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE || - pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT || - pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE); + Result = (pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE || + pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT || + pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE); + break; case FCmpInst::FCMP_OGT: // We know that C1 > C2 - return ConstantInt::get(Type::Int1Ty, - pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE || - pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT || - pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE); + Result = (pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE || + pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT || + pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE); + break; case FCmpInst::FCMP_OLE: // We know that C1 <= C2 // We can only partially decide this relation. if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) - return ConstantInt::getFalse(); - if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT) - return ConstantInt::getTrue(); + Result = 0; + else if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT) + Result = 1; break; case FCmpInst::FCMP_OGE: // We known that C1 >= C2 // We can only partially decide this relation. if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT) - return ConstantInt::getFalse(); - if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) - return ConstantInt::getTrue(); + Result = 0; + else if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) + Result = 1; break; case ICmpInst::ICMP_NE: // We know that C1 != C2 // We can only partially decide this relation. if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) - return ConstantInt::getFalse(); - if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) - return ConstantInt::getTrue(); + Result = 0; + else if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) + Result = 1; break; } + + // If we evaluated the result, return it now. + if (Result != -1) { + if (const VectorType *VT = dyn_cast(C1->getType())) { + if (Result == 0) + return Constant::getNullValue(VectorType::getInteger(VT)); + else + return Constant::getAllOnesValue(VectorType::getInteger(VT)); + } + return ConstantInt::get(Type::Int1Ty, Result); + } + } else { // Evaluate the relation between the two constants, per the predicate. + int Result = -1; // -1 = unknown, 0 = known false, 1 = known true. switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) { default: assert(0 && "Unknown relational!"); case ICmpInst::BAD_ICMP_PREDICATE: @@ -1303,69 +1454,80 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, case ICmpInst::ICMP_EQ: // We know the constants are equal! // If we know the constants are equal, we can decide the result of this // computation precisely. - return ConstantInt::get(Type::Int1Ty, - pred == ICmpInst::ICMP_EQ || - pred == ICmpInst::ICMP_ULE || - pred == ICmpInst::ICMP_SLE || - pred == ICmpInst::ICMP_UGE || - pred == ICmpInst::ICMP_SGE); + Result = (pred == ICmpInst::ICMP_EQ || + pred == ICmpInst::ICMP_ULE || + pred == ICmpInst::ICMP_SLE || + pred == ICmpInst::ICMP_UGE || + pred == ICmpInst::ICMP_SGE); + break; case ICmpInst::ICMP_ULT: // If we know that C1 < C2, we can decide the result of this computation // precisely. - return ConstantInt::get(Type::Int1Ty, - pred == ICmpInst::ICMP_ULT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_ULE); + Result = (pred == ICmpInst::ICMP_ULT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_ULE); + break; case ICmpInst::ICMP_SLT: // If we know that C1 < C2, we can decide the result of this computation // precisely. - return ConstantInt::get(Type::Int1Ty, - pred == ICmpInst::ICMP_SLT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_SLE); + Result = (pred == ICmpInst::ICMP_SLT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_SLE); + break; case ICmpInst::ICMP_UGT: // If we know that C1 > C2, we can decide the result of this computation // precisely. - return ConstantInt::get(Type::Int1Ty, - pred == ICmpInst::ICMP_UGT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_UGE); + Result = (pred == ICmpInst::ICMP_UGT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_UGE); + break; case ICmpInst::ICMP_SGT: // If we know that C1 > C2, we can decide the result of this computation // precisely. - return ConstantInt::get(Type::Int1Ty, - pred == ICmpInst::ICMP_SGT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_SGE); + Result = (pred == ICmpInst::ICMP_SGT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_SGE); + break; case ICmpInst::ICMP_ULE: // If we know that C1 <= C2, we can only partially decide this relation. - if (pred == ICmpInst::ICMP_UGT) return ConstantInt::getFalse(); - if (pred == ICmpInst::ICMP_ULT) return ConstantInt::getTrue(); + if (pred == ICmpInst::ICMP_UGT) Result = 0; + if (pred == ICmpInst::ICMP_ULT) Result = 1; break; case ICmpInst::ICMP_SLE: // If we know that C1 <= C2, we can only partially decide this relation. - if (pred == ICmpInst::ICMP_SGT) return ConstantInt::getFalse(); - if (pred == ICmpInst::ICMP_SLT) return ConstantInt::getTrue(); + if (pred == ICmpInst::ICMP_SGT) Result = 0; + if (pred == ICmpInst::ICMP_SLT) Result = 1; break; case ICmpInst::ICMP_UGE: // If we know that C1 >= C2, we can only partially decide this relation. - if (pred == ICmpInst::ICMP_ULT) return ConstantInt::getFalse(); - if (pred == ICmpInst::ICMP_UGT) return ConstantInt::getTrue(); + if (pred == ICmpInst::ICMP_ULT) Result = 0; + if (pred == ICmpInst::ICMP_UGT) Result = 1; break; case ICmpInst::ICMP_SGE: // If we know that C1 >= C2, we can only partially decide this relation. - if (pred == ICmpInst::ICMP_SLT) return ConstantInt::getFalse(); - if (pred == ICmpInst::ICMP_SGT) return ConstantInt::getTrue(); + if (pred == ICmpInst::ICMP_SLT) Result = 0; + if (pred == ICmpInst::ICMP_SGT) Result = 1; break; case ICmpInst::ICMP_NE: // If we know that C1 != C2, we can only partially decide this relation. - if (pred == ICmpInst::ICMP_EQ) return ConstantInt::getFalse(); - if (pred == ICmpInst::ICMP_NE) return ConstantInt::getTrue(); + if (pred == ICmpInst::ICMP_EQ) Result = 0; + if (pred == ICmpInst::ICMP_NE) Result = 1; break; } - + + // If we evaluated the result, return it now. + if (Result != -1) { + if (const VectorType *VT = dyn_cast(C1->getType())) { + if (Result == 0) + return Constant::getNullValue(VT); + else + return Constant::getAllOnesValue(VT); + } + return ConstantInt::get(Type::Int1Ty, Result); + } + if (!isa(C1) && isa(C2)) { // If C2 is a constant expr and C1 isn't, flop them around and fold the // other way if possible. @@ -1403,12 +1565,12 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, return const_cast(C); if (isa(C)) { - const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), + const PointerType *Ptr = cast(C->getType()); + const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, (Value **)Idxs, - (Value **)Idxs+NumIdx, - true); + (Value **)Idxs+NumIdx); assert(Ty != 0 && "Invalid indices for GEP!"); - return UndefValue::get(PointerType::get(Ty)); + return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace())); } Constant *Idx0 = Idxs[0]; @@ -1420,12 +1582,13 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, break; } if (isNull) { - const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), + const PointerType *Ptr = cast(C->getType()); + const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, (Value**)Idxs, - (Value**)Idxs+NumIdx, - true); + (Value**)Idxs+NumIdx); assert(Ty != 0 && "Invalid indices for GEP!"); - return ConstantPointerNull::get(PointerType::get(Ty)); + return + ConstantPointerNull::get(PointerType::get(Ty,Ptr->getAddressSpace())); } }