diff --git a/docs/LangRef.html b/docs/LangRef.html index c6cbe295465..9c4bbf094d3 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -1511,23 +1511,31 @@ following is the syntax for constant expressions:

fptoui ( CST to TYPE )
Convert a floating point constant to the corresponding unsigned integer - constant. TYPE must be an integer type. CST must be floating point. If the - value won't fit in the integer type, the results are undefined.
+ constant. TYPE must be a scalar or vector integer type. CST must be of scalar + or vector floating point type. Both CST and TYPE must be scalars, or vectors + of the same number of elements. If the value won't fit in the integer type, + the results are undefined.
fptosi ( CST to TYPE )
Convert a floating point constant to the corresponding signed integer - constant. TYPE must be an integer type. CST must be floating point. If the - value won't fit in the integer type, the results are undefined.
+ constant. TYPE must be a scalar or vector integer type. CST must be of scalar + or vector floating point type. Both CST and TYPE must be scalars, or vectors + of the same number of elements. If the value won't fit in the integer type, + the results are undefined.
uitofp ( CST to TYPE )
Convert an unsigned integer constant to the corresponding floating point - constant. TYPE must be floating point. CST must be of integer type. If the - value won't fit in the floating point type, the results are undefined.
+ constant. TYPE must be a scalar or vector floating point type. CST must be of + scalar or vector integer type. Both CST and TYPE must be scalars, or vectors + of the same number of elements. If the value won't fit in the floating point + type, the results are undefined.
sitofp ( CST to TYPE )
Convert a signed integer constant to the corresponding floating point - constant. TYPE must be floating point. CST must be of integer type. If the - value won't fit in the floating point type, the results are undefined.
+ constant. TYPE must be a scalar or vector floating point type. CST must be of + scalar or vector integer type. Both CST and TYPE must be scalars, or vectors + of the same number of elements. If the value won't fit in the floating point + type, the results are undefined.
ptrtoint ( CST to TYPE )
Convert a pointer typed constant to the corresponding integer constant @@ -3136,8 +3144,10 @@ unsigned integer equivalent of type ty2.
Arguments:

The 'fptoui' instruction takes a value to cast, which must be a -floating point value, and a type to cast it to, which -must be an integer type.

+scalar or vector floating point value, and a type +to cast it to ty2, which must be an integer +type. If ty is a vector floating point type, ty2 must be a +vector integer type with the same number of elements as ty

Semantics:

The 'fptoui' instruction converts its @@ -3169,11 +3179,12 @@ the results are undefined.

floating point value to type ty2.

-
Arguments:

The 'fptosi' instruction takes a value to cast, which must be a -floating point value, and a type to cast it to, which -must also be an integer type.

+scalar or vector floating point value, and a type +to cast it to ty2, which must be an integer +type. If ty is a vector floating point type, ty2 must be a +vector integer type with the same number of elements as ty

Semantics:

The 'fptosi' instruction converts its @@ -3204,18 +3215,18 @@ the results are undefined.

The 'uitofp' instruction regards value as an unsigned integer and converts that value to the ty2 type.

-
Arguments:
-

The 'uitofp' instruction takes a value to cast, which must be an -integer value, and a type to cast it to, which must -be a floating point type.

+

The 'uitofp' instruction takes a value to cast, which must be a +scalar or vector integer value, and a type to cast it +to ty2, which must be an floating point +type. If ty is a vector integer type, ty2 must be a vector +floating point type with the same number of elements as ty

Semantics:

The 'uitofp' instruction interprets its operand as an unsigned integer quantity and converts it to the corresponding floating point value. If the value cannot fit in the floating point value, the results are undefined.

-
Example:
   %X = uitofp i32 257 to float         ; yields float:257.0
@@ -3239,9 +3250,11 @@ the value cannot fit in the floating point value, the results are undefined.

integer and converts that value to the ty2 type.

Arguments:
-

The 'sitofp' instruction takes a value to cast, which must be an -integer value, and a type to cast it to, which must be -a floating point type.

+

The 'sitofp' instruction takes a value to cast, which must be a +scalar or vector integer value, and a type to cast it +to ty2, which must be an floating point +type. If ty is a vector integer type, ty2 must be a vector +floating point type with the same number of elements as ty

Semantics:

The 'sitofp' instruction interprets its operand as a signed diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index d17fbea7743..4ddcbf6babf 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 c79409bab7e..2c86e8d1c33 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 257e4813d1d..95140f3fe1d 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(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)); + 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(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)); + return ConstantVector::get(DestVecTy, res); + } return 0; case Instruction::ZExt: if (const ConstantInt *CI = dyn_cast(V)) { diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 74f62874501..49c27b82ccd 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 ed553e94ce8..6bee186e570 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(SrcTy)) { + if (const VectorType *DVTy = dyn_cast(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(SrcTy)) { + if (const VectorType *DVTy = dyn_cast(DstTy)) { + return SVTy->getElementType()->isFloatingPoint() && + DVTy->getElementType()->isInteger() && + SVTy->getNumElements() == DVTy->getNumElements(); + } + } return SrcTy->isFloatingPoint() && DstTy->isInteger(); case Instruction::PtrToInt: return isa(SrcTy) && DstTy->isInteger(); diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 5af9216fb42..6597af101c0 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(SrcTy)->getNumElements() == cast(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(SrcTy)->getNumElements() == cast(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(SrcTy)->getNumElements() == cast(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(SrcTy)->getNumElements() == cast(DestTy)->getNumElements(), + "FPToSI source and dest vector length mismatch", &I); visitInstruction(I); } diff --git a/test/Feature/newcasts.ll b/test/Feature/newcasts.ll index d2371573b7d..4cfc8bcf08e 100644 --- a/test/Feature/newcasts.ll +++ b/test/Feature/newcasts.ll @@ -15,6 +15,11 @@ define void @"NewCasts" (i16 %x) { %k = bitcast i32 %a to float %l = inttoptr i16 %x to i32* %m = ptrtoint i32* %l to i64 + %n = insertelement <4 x i32> undef, i32 %a, i32 0 + %o = sitofp <4 x i32> %n to <4 x float> + %p = uitofp <4 x i32> %n to <4 x float> + %q = fptosi <4 x float> %p to <4 x i32> + %r = fptoui <4 x float> %p to <4 x i32> ret void }