aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp6
-rw-r--r--lib/Target/X86/X86InstrSSE.td6
-rw-r--r--lib/VMCore/ConstantFold.cpp18
-rw-r--r--lib/VMCore/Constants.cpp26
-rw-r--r--lib/VMCore/Instructions.cpp16
-rw-r--r--lib/VMCore/Verifier.cpp48
6 files changed, 102 insertions, 18 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index d17fbea..4ddcbf6 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -6365,7 +6365,11 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
case ISD::FABS:
case ISD::FSQRT:
case ISD::FSIN:
- case ISD::FCOS: {
+ case ISD::FCOS:
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT:
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP: {
SDOperand L, H;
SplitVectorOp(Node->getOperand(0), L, H);
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index c79409b..2c86e8d 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -2967,6 +2967,12 @@ def : Pat<(v2i64 (and (xor VR128:$src1, (bc_v2i64 (v16i8 immAllOnesV))),
(memopv2i64 addr:$src2))),
(PANDNrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
+// vector -> vector casts
+def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
+ (Int_CVTDQ2PSrr VR128:$src)>, Requires<[HasSSE2]>;
+def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
+ (Int_CVTTPS2DQrr VR128:$src)>, Requires<[HasSSE2]>;
+
// Use movaps / movups for SSE integer load / store (one byte shorter).
def : Pat<(alignedloadv4i32 addr:$src),
(MOVAPSrm addr:$src)>, Requires<[HasSSE1]>;
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 257e481..95140f3 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -202,6 +202,15 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
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(ConstantFoldCastInstruction(opc, V->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?
@@ -224,6 +233,15 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
APFloat::rmNearestTiesToEven);
return ConstantFP::get(DestTy, 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(ConstantFoldCastInstruction(opc, V->getOperand(i),
+ DstEltTy));
+ return ConstantVector::get(DestVecTy, res);
+ }
return 0;
case Instruction::ZExt:
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 74f6287..49c27b8 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -1643,26 +1643,38 @@ Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
}
Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
- assert(C->getType()->isInteger() && Ty->isFloatingPoint() &&
- "This is an illegal i32 to floating point cast!");
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ bool toVec = Ty->getTypeID() == Type::VectorTyID;
+ assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
+ assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
+ "This is an illegal uint to floating point cast!");
return getFoldedCast(Instruction::UIToFP, C, Ty);
}
Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
- assert(C->getType()->isInteger() && Ty->isFloatingPoint() &&
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ bool toVec = Ty->getTypeID() == Type::VectorTyID;
+ assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
+ assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
"This is an illegal sint to floating point cast!");
return getFoldedCast(Instruction::SIToFP, C, Ty);
}
Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
- assert(C->getType()->isFloatingPoint() && Ty->isInteger() &&
- "This is an illegal floating point to i32 cast!");
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ bool toVec = Ty->getTypeID() == Type::VectorTyID;
+ assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
+ assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ "This is an illegal floating point to uint cast!");
return getFoldedCast(Instruction::FPToUI, C, Ty);
}
Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) {
- assert(C->getType()->isFloatingPoint() && Ty->isInteger() &&
- "This is an illegal floating point to i32 cast!");
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ bool toVec = Ty->getTypeID() == Type::VectorTyID;
+ assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
+ assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ "This is an illegal floating point to sint cast!");
return getFoldedCast(Instruction::FPToSI, C, Ty);
}
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index ed553e9..6bee186 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -1912,12 +1912,24 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() &&
SrcBitSize < DstBitSize;
case Instruction::UIToFP:
- return SrcTy->isInteger() && DstTy->isFloatingPoint();
case Instruction::SIToFP:
+ if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
+ if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
+ return SVTy->getElementType()->isInteger() &&
+ DVTy->getElementType()->isFloatingPoint() &&
+ SVTy->getNumElements() == DVTy->getNumElements();
+ }
+ }
return SrcTy->isInteger() && DstTy->isFloatingPoint();
case Instruction::FPToUI:
- return SrcTy->isFloatingPoint() && DstTy->isInteger();
case Instruction::FPToSI:
+ if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
+ if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
+ return SVTy->getElementType()->isFloatingPoint() &&
+ DVTy->getElementType()->isInteger() &&
+ SVTy->getNumElements() == DVTy->getNumElements();
+ }
+ }
return SrcTy->isFloatingPoint() && DstTy->isInteger();
case Instruction::PtrToInt:
return isa<PointerType>(SrcTy) && DstTy->isInteger();
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 5af9216..6597af1 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -709,8 +709,16 @@ void Verifier::visitUIToFPInst(UIToFPInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- Assert1(SrcTy->isInteger(),"UInt2FP source must be integral", &I);
- Assert1(DestTy->isFloatingPoint(),"UInt2FP result must be FP", &I);
+ bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
+ bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
+
+ Assert1(SrcVec == DstVec,"UIToFP source and dest must both be vector or scalar", &I);
+ Assert1(SrcTy->isIntOrIntVector(),"UIToFP source must be integer or integer vector", &I);
+ Assert1(DestTy->isFPOrFPVector(),"UIToFP result must be FP or FP vector", &I);
+
+ if (SrcVec && DstVec)
+ Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
+ "UIToFP source and dest vector length mismatch", &I);
visitInstruction(I);
}
@@ -720,8 +728,16 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- Assert1(SrcTy->isInteger(),"SInt2FP source must be integral", &I);
- Assert1(DestTy->isFloatingPoint(),"SInt2FP result must be FP", &I);
+ bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
+ bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
+
+ Assert1(SrcVec == DstVec,"SIToFP source and dest must both be vector or scalar", &I);
+ Assert1(SrcTy->isIntOrIntVector(),"SIToFP source must be integer or integer vector", &I);
+ Assert1(DestTy->isFPOrFPVector(),"SIToFP result must be FP or FP vector", &I);
+
+ if (SrcVec && DstVec)
+ Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
+ "SIToFP source and dest vector length mismatch", &I);
visitInstruction(I);
}
@@ -731,8 +747,16 @@ void Verifier::visitFPToUIInst(FPToUIInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- Assert1(SrcTy->isFloatingPoint(),"FP2UInt source must be FP", &I);
- Assert1(DestTy->isInteger(),"FP2UInt result must be integral", &I);
+ bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
+ bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
+
+ Assert1(SrcVec == DstVec,"FPToUI source and dest must both be vector or scalar", &I);
+ Assert1(SrcTy->isFPOrFPVector(),"FPToUI source must be FP or FP vector", &I);
+ Assert1(DestTy->isIntOrIntVector(),"FPToUI result must be integer or integer vector", &I);
+
+ if (SrcVec && DstVec)
+ Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
+ "FPToUI source and dest vector length mismatch", &I);
visitInstruction(I);
}
@@ -742,8 +766,16 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- Assert1(SrcTy->isFloatingPoint(),"FPToSI source must be FP", &I);
- Assert1(DestTy->isInteger(),"FP2ToI result must be integral", &I);
+ bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
+ bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
+
+ Assert1(SrcVec == DstVec,"FPToSI source and dest must both be vector or scalar", &I);
+ Assert1(SrcTy->isFPOrFPVector(),"FPToSI source must be FP or FP vector", &I);
+ Assert1(DestTy->isIntOrIntVector(),"FPToSI result must be integer or integer vector", &I);
+
+ if (SrcVec && DstVec)
+ Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
+ "FPToSI source and dest vector length mismatch", &I);
visitInstruction(I);
}