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) {