Commit b63cd886 by Jim Stichnoth

Subzero: Use cvttss2si and similar instead of cvtss2si for fp->int casts.

This is the truncating cvt instruction instead of rounding. A few interesting floating point inputs are added to the cross tests. Also, the cross test error output is modified to be more clear. BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/550723002
parent c836acb8
......@@ -28,7 +28,7 @@ namespace Subzero_ {
#define XSTR(s) STR(s)
#define STR(s) #s
#define COMPARE(Func, FromCName, ToCName, Input) \
#define COMPARE(Func, FromCName, ToCName, Input, FromString) \
do { \
ToCName ResultSz, ResultLlc; \
ResultLlc = Func<FromCName, ToCName>(Input); \
......@@ -38,26 +38,30 @@ namespace Subzero_ {
++Passes; \
} else { \
++Failures; \
std::cout << std::fixed << XSTR(Func) \
<< "<" XSTR(FromCName) ", " XSTR(ToCName) ">(" << Input \
<< "): sz=" << ResultSz << " llc=" << ResultLlc << "\n"; \
std::cout << std::fixed << XSTR(Func) << "<" << FromString \
<< ", " XSTR(ToCName) ">(" << Input << "): "; \
if (sizeof(ToCName) == 1) \
std::cout << "sz=" << (int)ResultSz << " llc=" << (int)ResultLlc; \
else \
std::cout << "sz=" << ResultSz << " llc=" << ResultLlc; \
std::cout << "\n"; \
} \
} while (0)
template <typename FromType>
void testValue(FromType Val, size_t &TotalTests, size_t &Passes,
size_t &Failures) {
COMPARE(cast, FromType, bool, Val);
COMPARE(cast, FromType, uint8_t, Val);
COMPARE(cast, FromType, myint8_t, Val);
COMPARE(cast, FromType, uint16_t, Val);
COMPARE(cast, FromType, int16_t, Val);
COMPARE(cast, FromType, uint32_t, Val);
COMPARE(cast, FromType, int32_t, Val);
COMPARE(cast, FromType, uint64_t, Val);
COMPARE(cast, FromType, int64_t, Val);
COMPARE(cast, FromType, float, Val);
COMPARE(cast, FromType, double, Val);
size_t &Failures, const char *FromTypeString) {
COMPARE(cast, FromType, bool, Val, FromTypeString);
COMPARE(cast, FromType, uint8_t, Val, FromTypeString);
COMPARE(cast, FromType, myint8_t, Val, FromTypeString);
COMPARE(cast, FromType, uint16_t, Val, FromTypeString);
COMPARE(cast, FromType, int16_t, Val, FromTypeString);
COMPARE(cast, FromType, uint32_t, Val, FromTypeString);
COMPARE(cast, FromType, int32_t, Val, FromTypeString);
COMPARE(cast, FromType, uint64_t, Val, FromTypeString);
COMPARE(cast, FromType, int64_t, Val, FromTypeString);
COMPARE(cast, FromType, float, Val, FromTypeString);
COMPARE(cast, FromType, double, Val, FromTypeString);
}
int main(int argc, char **argv) {
......@@ -128,7 +132,9 @@ int main(int argc, char **argv) {
static const size_t NumValsSi64 = sizeof(ValsSi64) / sizeof(*ValsSi64);
volatile float ValsF32[] = {
0, 1, 0x7e,
0, 1, 1.4,
1.5, 1.6, -1.4,
-1.5, -1.6, 0x7e,
0x7f, 0x80, 0x81,
0xfe, 0xff, 0x7ffe,
0x7fff, 0x8000, 0x8001,
......@@ -142,7 +148,9 @@ int main(int argc, char **argv) {
static const size_t NumValsF32 = sizeof(ValsF32) / sizeof(*ValsF32);
volatile double ValsF64[] = {
0, 1, 0x7e,
0, 1, 1.4,
1.5, 1.6, -1.4,
-1.5, -1.6, 0x7e,
0x7f, 0x80, 0x81,
0xfe, 0xff, 0x7ffe,
0x7fff, 0x8000, 0x8001,
......@@ -157,49 +165,49 @@ int main(int argc, char **argv) {
for (size_t i = 0; i < NumValsUi1; ++i) {
bool Val = ValsUi1[i];
testValue<bool>(Val, TotalTests, Passes, Failures);
testValue<bool>(Val, TotalTests, Passes, Failures, "bool");
}
for (size_t i = 0; i < NumValsUi8; ++i) {
uint8_t Val = ValsUi8[i];
testValue<uint8_t>(Val, TotalTests, Passes, Failures);
testValue<uint8_t>(Val, TotalTests, Passes, Failures, "uint8_t");
}
for (size_t i = 0; i < NumValsSi8; ++i) {
myint8_t Val = ValsSi8[i];
testValue<myint8_t>(Val, TotalTests, Passes, Failures);
testValue<myint8_t>(Val, TotalTests, Passes, Failures, "int8_t");
}
for (size_t i = 0; i < NumValsUi16; ++i) {
uint16_t Val = ValsUi16[i];
testValue<uint16_t>(Val, TotalTests, Passes, Failures);
testValue<uint16_t>(Val, TotalTests, Passes, Failures, "uint16_t");
}
for (size_t i = 0; i < NumValsSi16; ++i) {
int16_t Val = ValsSi16[i];
testValue<int16_t>(Val, TotalTests, Passes, Failures);
testValue<int16_t>(Val, TotalTests, Passes, Failures, "int16_t");
}
for (size_t i = 0; i < NumValsUi32; ++i) {
uint32_t Val = ValsUi32[i];
testValue<uint32_t>(Val, TotalTests, Passes, Failures);
COMPARE(castBits, uint32_t, float, Val);
testValue<uint32_t>(Val, TotalTests, Passes, Failures, "uint32_t");
COMPARE(castBits, uint32_t, float, Val, "uint32_t");
}
for (size_t i = 0; i < NumValsSi32; ++i) {
int32_t Val = ValsSi32[i];
testValue<int32_t>(Val, TotalTests, Passes, Failures);
testValue<int32_t>(Val, TotalTests, Passes, Failures, "int32_t");
}
for (size_t i = 0; i < NumValsUi64; ++i) {
uint64_t Val = ValsUi64[i];
testValue<uint64_t>(Val, TotalTests, Passes, Failures);
COMPARE(castBits, uint64_t, double, Val);
testValue<uint64_t>(Val, TotalTests, Passes, Failures, "uint64_t");
COMPARE(castBits, uint64_t, double, Val, "uint64_t");
}
for (size_t i = 0; i < NumValsSi64; ++i) {
int64_t Val = ValsSi64[i];
testValue<int64_t>(Val, TotalTests, Passes, Failures);
testValue<int64_t>(Val, TotalTests, Passes, Failures, "int64_t");
}
for (size_t i = 0; i < NumValsF32; ++i) {
for (unsigned j = 0; j < 2; ++j) {
float Val = ValsF32[i];
if (j > 0)
Val = -Val;
testValue<float>(Val, TotalTests, Passes, Failures);
COMPARE(castBits, float, uint32_t, Val);
testValue<float>(Val, TotalTests, Passes, Failures, "float");
COMPARE(castBits, float, uint32_t, Val, "float");
}
}
for (size_t i = 0; i < NumValsF64; ++i) {
......@@ -207,8 +215,8 @@ int main(int argc, char **argv) {
double Val = ValsF64[i];
if (j > 0)
Val = -Val;
testValue<double>(Val, TotalTests, Passes, Failures);
COMPARE(castBits, double, uint64_t, Val);
testValue<double>(Val, TotalTests, Passes, Failures, "double");
COMPARE(castBits, double, uint64_t, Val, "double");
}
}
......
......@@ -182,8 +182,9 @@ InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Addr,
addSource(Ebx);
}
InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source)
: InstX8632(Func, InstX8632::Cvt, 1, Dest) {
InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source,
bool Trunc)
: InstX8632(Func, InstX8632::Cvt, 1, Dest), Trunc(Trunc) {
addSource(Source);
}
......@@ -798,7 +799,10 @@ void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
void InstX8632Cvt::emit(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 1);
Str << "\tcvt" << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
Str << "\tcvt";
if (Trunc)
Str << "t";
Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
<< TypeX8632Attributes[getDest()->getType()].CvtString << "\t";
getDest()->emit(Func);
Str << ", ";
......@@ -809,8 +813,11 @@ void InstX8632Cvt::emit(const Cfg *Func) const {
void InstX8632Cvt::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
dumpDest(Func);
Str << " = cvt" << TypeX8632Attributes[getSrc(0)->getType()].CvtString
<< "2" << TypeX8632Attributes[getDest()->getType()].CvtString << " ";
Str << " = cvt";
if (Trunc)
Str << "t";
Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
<< TypeX8632Attributes[getDest()->getType()].CvtString << " ";
dumpSources(Func);
}
......
......@@ -863,16 +863,18 @@ private:
// operand needs to be done separately.
class InstX8632Cvt : public InstX8632 {
public:
static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source) {
static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
bool Trunc) {
return new (Func->allocate<InstX8632Cvt>())
InstX8632Cvt(Func, Dest, Source);
InstX8632Cvt(Func, Dest, Source, Trunc);
}
virtual void emit(const Cfg *Func) const;
virtual void dump(const Cfg *Func) const;
static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
private:
InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source);
bool Trunc;
InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, bool Trunc);
InstX8632Cvt(const InstX8632Cvt &) LLVM_DELETED_FUNCTION;
InstX8632Cvt &operator=(const InstX8632Cvt &) LLVM_DELETED_FUNCTION;
virtual ~InstX8632Cvt() {}
......
......@@ -2057,7 +2057,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
Inst->getSrc(0)->getType() == IceType_v4f32);
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
Variable *T = makeReg(Dest->getType());
_cvt(T, Src0RM);
_cvtt(T, Src0RM);
_movp(Dest, T);
} else if (Dest->getType() == IceType_i64) {
// Use a helper for converting floating-point values to 64-bit
......@@ -2079,7 +2079,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
Variable *T_1 = makeReg(IceType_i32);
Variable *T_2 = makeReg(Dest->getType());
_cvt(T_1, Src0RM);
_cvtt(T_1, Src0RM);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types
_mov(Dest, T_2);
T_2->setPreferredRegister(T_1, true);
......@@ -2114,7 +2114,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
Variable *T_1 = makeReg(IceType_i32);
Variable *T_2 = makeReg(Dest->getType());
_cvt(T_1, Src0RM);
_cvtt(T_1, Src0RM);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types
_mov(Dest, T_2);
T_2->setPreferredRegister(T_1, true);
......
......@@ -264,7 +264,12 @@ protected:
Context.insert(InstFakeDef::create(Func, Eax));
}
void _cvt(Variable *Dest, Operand *Src0) {
Context.insert(InstX8632Cvt::create(Func, Dest, Src0));
const bool Trunc = false;
Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Trunc));
}
void _cvtt(Variable *Dest, Operand *Src0) {
const bool Trunc = true;
Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Trunc));
}
void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1));
......
......@@ -271,7 +271,7 @@ entry:
ret i32 %conv
}
; CHECK-LABEL: doubleToSigned32
; CHECK: cvtsd2si
; CHECK: cvttsd2si
define internal i32 @floatToSigned32(float %a) {
entry:
......@@ -279,7 +279,7 @@ entry:
ret i32 %conv
}
; CHECK-LABEL: floatToSigned32
; CHECK: cvtss2si
; CHECK: cvttss2si
define internal i32 @doubleToUnsigned32(double %a) {
entry:
......@@ -309,7 +309,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToSigned16
; CHECK: cvtsd2si
; CHECK: cvttsd2si
; CHECK: movsx
define internal i32 @floatToSigned16(float %a) {
......@@ -319,7 +319,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToSigned16
; CHECK: cvtss2si
; CHECK: cvttss2si
; CHECK: movsx
define internal i32 @doubleToUnsigned16(double %a) {
......@@ -329,7 +329,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToUnsigned16
; CHECK: cvtsd2si
; CHECK: cvttsd2si
; CHECK: movzx
define internal i32 @floatToUnsigned16(float %a) {
......@@ -339,7 +339,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToUnsigned16
; CHECK: cvtss2si
; CHECK: cvttss2si
; CHECK: movzx
define internal i32 @doubleToSigned8(double %a) {
......@@ -349,7 +349,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToSigned8
; CHECK: cvtsd2si
; CHECK: cvttsd2si
; CHECK: movsx
define internal i32 @floatToSigned8(float %a) {
......@@ -359,7 +359,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToSigned8
; CHECK: cvtss2si
; CHECK: cvttss2si
; CHECK: movsx
define internal i32 @doubleToUnsigned8(double %a) {
......@@ -369,7 +369,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToUnsigned8
; CHECK: cvtsd2si
; CHECK: cvttsd2si
; CHECK: movzx
define internal i32 @floatToUnsigned8(float %a) {
......@@ -379,7 +379,7 @@ entry:
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToUnsigned8
; CHECK: cvtss2si
; CHECK: cvttss2si
; CHECK: movzx
define internal i32 @doubleToUnsigned1(double %a) {
......@@ -389,7 +389,7 @@ entry:
ret i32 %tobool.ret_ext
}
; CHECK-LABEL: doubleToUnsigned1
; CHECK: cvtsd2si
; CHECK: cvttsd2si
; CHECK: and eax, 1
define internal i32 @floatToUnsigned1(float %a) {
......@@ -399,7 +399,7 @@ entry:
ret i32 %tobool.ret_ext
}
; CHECK-LABEL: floatToUnsigned1
; CHECK: cvtss2si
; CHECK: cvttss2si
; CHECK: and eax, 1
define internal double @signed64ToDouble(i64 %a) {
......
......@@ -138,7 +138,7 @@ entry:
ret <4 x i32> %res
; CHECK-LABEL: test_fptosi_v4f32_to_v4i32:
; CHECK: cvtps2dq
; CHECK: cvttps2dq
}
define <4 x i32> @test_fptoui_v4f32_to_v4i32(<4 x float> %arg) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment