mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-18 01:37:56 +00:00
Add support for vectors to int <-> float casts.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44204 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
247fdca789
commit
b348d18caf
@ -1511,23 +1511,31 @@ following is the syntax for constant expressions:</p>
|
||||
|
||||
<dt><b><tt>fptoui ( CST to TYPE )</tt></b></dt>
|
||||
<dd>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.</dd>
|
||||
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.</dd>
|
||||
|
||||
<dt><b><tt>fptosi ( CST to TYPE )</tt></b></dt>
|
||||
<dd>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.</dd>
|
||||
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.</dd>
|
||||
|
||||
<dt><b><tt>uitofp ( CST to TYPE )</tt></b></dt>
|
||||
<dd>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.</dd>
|
||||
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.</dd>
|
||||
|
||||
<dt><b><tt>sitofp ( CST to TYPE )</tt></b></dt>
|
||||
<dd>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.</dd>
|
||||
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.</dd>
|
||||
|
||||
<dt><b><tt>ptrtoint ( CST to TYPE )</tt></b></dt>
|
||||
<dd>Convert a pointer typed constant to the corresponding integer constant
|
||||
@ -3136,8 +3144,10 @@ unsigned integer equivalent of type <tt>ty2</tt>.
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The '<tt>fptoui</tt>' instruction takes a value to cast, which must be a
|
||||
<a href="#t_floating">floating point</a> value, and a type to cast it to, which
|
||||
must be an <a href="#t_integer">integer</a> type.</p>
|
||||
scalar or vector <a href="#t_floating">floating point</a> value, and a type
|
||||
to cast it to <tt>ty2</tt>, which must be an <a href="#t_integer">integer</a>
|
||||
type. If <tt>ty</tt> is a vector floating point type, <tt>ty2</tt> must be a
|
||||
vector integer type with the same number of elements as <tt>ty</tt></p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p> The '<tt>fptoui</tt>' instruction converts its
|
||||
@ -3169,11 +3179,12 @@ the results are undefined.</p>
|
||||
<a href="#t_floating">floating point</a> <tt>value</tt> to type <tt>ty2</tt>.
|
||||
</p>
|
||||
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p> The '<tt>fptosi</tt>' instruction takes a value to cast, which must be a
|
||||
<a href="#t_floating">floating point</a> value, and a type to cast it to, which
|
||||
must also be an <a href="#t_integer">integer</a> type.</p>
|
||||
scalar or vector <a href="#t_floating">floating point</a> value, and a type
|
||||
to cast it to <tt>ty2</tt>, which must be an <a href="#t_integer">integer</a>
|
||||
type. If <tt>ty</tt> is a vector floating point type, <tt>ty2</tt> must be a
|
||||
vector integer type with the same number of elements as <tt>ty</tt></p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>The '<tt>fptosi</tt>' instruction converts its
|
||||
@ -3204,18 +3215,18 @@ the results are undefined.</p>
|
||||
<p>The '<tt>uitofp</tt>' instruction regards <tt>value</tt> as an unsigned
|
||||
integer and converts that value to the <tt>ty2</tt> type.</p>
|
||||
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The '<tt>uitofp</tt>' instruction takes a value to cast, which must be an
|
||||
<a href="#t_integer">integer</a> value, and a type to cast it to, which must
|
||||
be a <a href="#t_floating">floating point</a> type.</p>
|
||||
<p>The '<tt>uitofp</tt>' instruction takes a value to cast, which must be a
|
||||
scalar or vector <a href="#t_integer">integer</a> value, and a type to cast it
|
||||
to <tt>ty2</tt>, which must be an <a href="#t_floating">floating point</a>
|
||||
type. If <tt>ty</tt> is a vector integer type, <tt>ty2</tt> must be a vector
|
||||
floating point type with the same number of elements as <tt>ty</tt></p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>The '<tt>uitofp</tt>' 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.</p>
|
||||
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%X = uitofp i32 257 to float <i>; yields float:257.0</i>
|
||||
@ -3239,9 +3250,11 @@ the value cannot fit in the floating point value, the results are undefined.</p>
|
||||
integer and converts that value to the <tt>ty2</tt> type.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The '<tt>sitofp</tt>' instruction takes a value to cast, which must be an
|
||||
<a href="#t_integer">integer</a> value, and a type to cast it to, which must be
|
||||
a <a href="#t_floating">floating point</a> type.</p>
|
||||
<p>The '<tt>sitofp</tt>' instruction takes a value to cast, which must be a
|
||||
scalar or vector <a href="#t_integer">integer</a> value, and a type to cast it
|
||||
to <tt>ty2</tt>, which must be an <a href="#t_floating">floating point</a>
|
||||
type. If <tt>ty</tt> is a vector integer type, <tt>ty2</tt> must be a vector
|
||||
floating point type with the same number of elements as <tt>ty</tt></p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>The '<tt>sitofp</tt>' instruction interprets its operand as a signed
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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]>;
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user