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
diff --git a/crosstest/test_cast_main.cpp b/crosstest/test_cast_main.cpp
index 414fcbb..7407a59 100644
--- a/crosstest/test_cast_main.cpp
+++ b/crosstest/test_cast_main.cpp
@@ -28,7 +28,7 @@
#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 @@
++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 @@
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 @@
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 @@
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 @@
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");
}
}
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index 1454778..373ab59 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -182,8 +182,9 @@
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 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::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);
}
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
index 834e061..04902d2 100644
--- a/src/IceInstX8632.h
+++ b/src/IceInstX8632.h
@@ -863,16 +863,18 @@
// 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() {}
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 7b97758..6fced4d 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -2057,7 +2057,7 @@
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 @@
// 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 @@
// 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);
diff --git a/src/IceTargetLoweringX8632.h b/src/IceTargetLoweringX8632.h
index 6f8ee02..251baa2 100644
--- a/src/IceTargetLoweringX8632.h
+++ b/src/IceTargetLoweringX8632.h
@@ -264,7 +264,12 @@
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));
diff --git a/tests_lit/llvm2ice_tests/fp.pnacl.ll b/tests_lit/llvm2ice_tests/fp.pnacl.ll
index ab2f439..424fe3a 100644
--- a/tests_lit/llvm2ice_tests/fp.pnacl.ll
+++ b/tests_lit/llvm2ice_tests/fp.pnacl.ll
@@ -271,7 +271,7 @@
ret i32 %conv
}
; CHECK-LABEL: doubleToSigned32
-; CHECK: cvtsd2si
+; CHECK: cvttsd2si
define internal i32 @floatToSigned32(float %a) {
entry:
@@ -279,7 +279,7 @@
ret i32 %conv
}
; CHECK-LABEL: floatToSigned32
-; CHECK: cvtss2si
+; CHECK: cvttss2si
define internal i32 @doubleToUnsigned32(double %a) {
entry:
@@ -309,7 +309,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToSigned16
-; CHECK: cvtsd2si
+; CHECK: cvttsd2si
; CHECK: movsx
define internal i32 @floatToSigned16(float %a) {
@@ -319,7 +319,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToSigned16
-; CHECK: cvtss2si
+; CHECK: cvttss2si
; CHECK: movsx
define internal i32 @doubleToUnsigned16(double %a) {
@@ -329,7 +329,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToUnsigned16
-; CHECK: cvtsd2si
+; CHECK: cvttsd2si
; CHECK: movzx
define internal i32 @floatToUnsigned16(float %a) {
@@ -339,7 +339,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToUnsigned16
-; CHECK: cvtss2si
+; CHECK: cvttss2si
; CHECK: movzx
define internal i32 @doubleToSigned8(double %a) {
@@ -349,7 +349,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToSigned8
-; CHECK: cvtsd2si
+; CHECK: cvttsd2si
; CHECK: movsx
define internal i32 @floatToSigned8(float %a) {
@@ -359,7 +359,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToSigned8
-; CHECK: cvtss2si
+; CHECK: cvttss2si
; CHECK: movsx
define internal i32 @doubleToUnsigned8(double %a) {
@@ -369,7 +369,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: doubleToUnsigned8
-; CHECK: cvtsd2si
+; CHECK: cvttsd2si
; CHECK: movzx
define internal i32 @floatToUnsigned8(float %a) {
@@ -379,7 +379,7 @@
ret i32 %conv.ret_ext
}
; CHECK-LABEL: floatToUnsigned8
-; CHECK: cvtss2si
+; CHECK: cvttss2si
; CHECK: movzx
define internal i32 @doubleToUnsigned1(double %a) {
@@ -389,7 +389,7 @@
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 @@
ret i32 %tobool.ret_ext
}
; CHECK-LABEL: floatToUnsigned1
-; CHECK: cvtss2si
+; CHECK: cvttss2si
; CHECK: and eax, 1
define internal double @signed64ToDouble(i64 %a) {
diff --git a/tests_lit/llvm2ice_tests/vector-cast.ll b/tests_lit/llvm2ice_tests/vector-cast.ll
index 363ab98..5b0cb1a 100644
--- a/tests_lit/llvm2ice_tests/vector-cast.ll
+++ b/tests_lit/llvm2ice_tests/vector-cast.ll
@@ -138,7 +138,7 @@
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) {