if (const VectorType *SrcTy = dyn_cast<VectorType>(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<ConstantAggregateZero>(V))
return Constant::getNullValue(DestTy);
if (ConstantVector *CV = dyn_cast<ConstantVector>(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<ConstantInt>(V) || isa<ConstantFP>(V))
+ return ConstantExpr::getBitCast(ConstantVector::get(&V, 1), DestPTy);
}
// Finally, implement bitcast folding now. The code below doesn't handle
if (const ConstantFP *FP = dyn_cast<ConstantFP>(V)) {
// FP -> Integral.
if (DestTy == Type::Int32Ty) {
- return ConstantInt::get(FP->getValueAPF().convertToAPInt());
+ return ConstantInt::get(FP->getValueAPF().bitcastToAPInt());
} 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;
case Instruction::FPTrunc:
case Instruction::FPExt:
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(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.
case Instruction::FPToSI:
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
const APFloat &V = FPC->getValueAPF();
+ bool ignored;
uint64_t x[2];
uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth();
(void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI,
- APFloat::rmTowardZero);
+ APFloat::rmTowardZero, &ignored);
APInt Val(DestBitWidth, 2, x);
return ConstantInt::get(Val);
}
const VectorType *DestVecTy = cast<VectorType>(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.
const VectorType *DestVecTy = cast<VectorType>(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;
const Constant *Mask) {
// Undefined shuffle mask -> undefined value.
if (isa<UndefValue>(Mask)) return UndefValue::get(V1->getType());
-
- unsigned NumElts = cast<VectorType>(V1->getType())->getNumElements();
+
+ unsigned MaskNumElts = cast<VectorType>(Mask->getType())->getNumElements();
+ unsigned SrcNumElts = cast<VectorType>(V1->getType())->getNumElements();
const Type *EltTy = cast<VectorType>(V1->getType())->getElementType();
-
+
// Loop over the shuffle mask, evaluating each element.
SmallVector<Constant*, 32> 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<UndefValue>(InElt))
InElt = UndefValue::get(EltTy);
else if (ConstantInt *CI = dyn_cast<ConstantInt>(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;
}
Result.push_back(InElt);
}
-
+
return ConstantVector::get(&Result[0], Result.size());
}
return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan ||
R==APFloat::cmpEqual);
}
- } else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) {
- if (const ConstantVector *CP2 = dyn_cast<ConstantVector>(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,
- CP1->getOperand(i),
- CP2->getOperand(i));
- if (ConstantInt *CB = dyn_cast<ConstantInt>(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,
- CP1->getOperand(i),
- CP2->getOperand(i));
- if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
- return CB;
- }
- // Otherwise, could not decide from any element pairs.
- return 0;
+ } else if (isa<VectorType>(C1->getType())) {
+ SmallVector<Constant*, 16> 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<Constant*, 4> 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<ConstantInt>(C)) {
+ if (CI->isZero())
+ ResElts.push_back(Constant::getNullValue(ResEltTy));
+ else
+ ResElts.push_back(Constant::getAllOnesValue(ResEltTy));
+ } else if (isa<UndefValue>(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;
+ int Result = -1; // -1 = unknown, 0 = known false, 1 = known true.
switch (evaluateFCmpRelation(C1, C2)) {
default: assert(0 && "Unknown relation!");
case FCmpInst::FCMP_UNO: