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);
// 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<ConstantFP>(V)) {
+ if (const ConstantFP *FP = dyn_cast<ConstantFP>(V))
// FP -> Integral.
- if (DestTy == Type::Int32Ty) {
- return ConstantInt::get(FP->getValueAPF().bitcastToAPInt());
- } else {
- assert(DestTy == Type::Int64Ty && "only support f32/f64 for now!");
- return ConstantInt::get(FP->getValueAPF().bitcastToAPInt());
- }
- }
+ return ConstantInt::get(FP->getValueAPF().bitcastToAPInt());
+
return 0;
}
}
}
+ // 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<ConstantVector>(V))
+ if (isa<VectorType>(DestTy) &&
+ cast<VectorType>(DestTy)->getNumElements() ==
+ CV->getType()->getNumElements()) {
+ std::vector<Constant*> res;
+ 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(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) {
APInt Val(DestBitWidth, 2, x);
return ConstantInt::get(Val);
}
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
- std::vector<Constant*> res;
- 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(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?
APFloat::rmNearestTiesToEven);
return ConstantFP::get(apf);
}
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
- std::vector<Constant*> res;
- 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(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy));
- return ConstantVector::get(DestVecTy, res);
- }
return 0;
case Instruction::ZExt:
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
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 Constant::getNullValue(C1->getType());
case Instruction::UDiv:
case Instruction::SDiv:
- case Instruction::FDiv:
case Instruction::URem:
case Instruction::SRem:
- case Instruction::FRem:
if (!isa<UndefValue>(C2)) // undef / X -> 0
return Constant::getNullValue(C1->getType());
return const_cast<Constant*>(C2); // X / undef -> undef
case Instruction::SDiv:
if (CI2->equalsInt(1))
return const_cast<Constant*>(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<Constant*>(C2); // X & 0 == 0
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);
switch (Opcode) {
default:
break;
- case Instruction::Add:
+ case Instruction::FAdd:
(void)C3V.add(C2V, APFloat::rmNearestTiesToEven);
return ConstantFP::get(C3V);
- case Instruction::Sub:
+ case Instruction::FSub:
(void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven);
return ConstantFP::get(C3V);
- case Instruction::Mul:
+ case Instruction::FMul:
(void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven);
return ConstantFP::get(C3V);
case Instruction::FDiv:
(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<double>::
- quiet_NaN()));
- if (CFP1->getType() == Type::FloatTy)
- return ConstantFP::get(APFloat(std::numeric_limits<float>::
- quiet_NaN()));
- break;
- }
(void)C3V.mod(C2V, APFloat::rmNearestTiesToEven);
return ConstantFP::get(C3V);
}
switch (Opcode) {
default:
break;
- case Instruction::Add:
+ case Instruction::Add:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAdd);
- case Instruction::Sub:
+ case Instruction::FAdd:
+ return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFAdd);
+ case Instruction::Sub:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSub);
- case Instruction::Mul:
+ case Instruction::FSub:
+ return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFSub);
+ case Instruction::Mul:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getMul);
+ case Instruction::FMul:
+ return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFMul);
case Instruction::UDiv:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getUDiv);
case Instruction::SDiv:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getOr);
case Instruction::Xor:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getXor);
+ case Instruction::LShr:
+ return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getLShr);
+ case Instruction::AShr:
+ return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAShr);
+ case Instruction::Shl:
+ return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getShl);
}
}
}
// other way if possible.
switch (Opcode) {
case Instruction::Add:
+ case Instruction::FAdd:
case Instruction::Mul:
+ case Instruction::FMul:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::Sub:
+ case Instruction::FSub:
case Instruction::SDiv:
case Instruction::UDiv:
case Instruction::FDiv:
Offset = ConstantExpr::getSExt(Offset, Base->getType());
else if (Base->getType()->getPrimitiveSizeInBits() <
Offset->getType()->getPrimitiveSizeInBits())
- Base = ConstantExpr::getZExt(Base, Base->getType());
+ Base = ConstantExpr::getZExt(Base, Offset->getType());
Base = ConstantExpr::getAdd(Base, Offset);
return ConstantExpr::getIntToPtr(Base, CE->getType());