Skip to content

Commit

Permalink
Add support for vectors to int <-> float casts.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44204 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
sampo3k committed Nov 17, 2007
1 parent 247fdca commit b348d18
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 39 deletions.
55 changes: 34 additions & 21 deletions docs/LangRef.html
Original file line number Diff line number Diff line change
Expand Up @@ -1511,23 +1511,31 @@ <h5>Examples:</h5>

<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
Expand Down Expand Up @@ -3136,8 +3144,10 @@ <h5>Overview:</h5>

<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
Expand Down Expand Up @@ -3169,11 +3179,12 @@ <h5>Overview:</h5>
<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
Expand Down Expand Up @@ -3204,18 +3215,18 @@ <h5>Overview:</h5>
<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>
Expand All @@ -3239,9 +3250,11 @@ <h5>Overview:</h5>
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
Expand Down
6 changes: 5 additions & 1 deletion lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 6 additions & 0 deletions lib/Target/X86/X86InstrSSE.td
Original file line number Diff line number Diff line change
Expand Up @@ -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]>;
Expand Down
18 changes: 18 additions & 0 deletions lib/VMCore/ConstantFold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -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)) {
Expand Down
26 changes: 19 additions & 7 deletions lib/VMCore/Constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
16 changes: 14 additions & 2 deletions lib/VMCore/Instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
48 changes: 40 additions & 8 deletions lib/VMCore/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand Down
5 changes: 5 additions & 0 deletions test/Feature/newcasts.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down

0 comments on commit b348d18

Please sign in to comment.