Implement long to float cast for x86
authorMike Danes <onemihaid@hotmail.com>
Sun, 11 Sep 2016 12:49:12 +0000 (15:49 +0300)
committerMike Danes <onemihaid@hotmail.com>
Mon, 12 Sep 2016 04:35:43 +0000 (07:35 +0300)
Convert long to float/double casts to helper calls. Despite the call this version is 2x faster than JIT32's FILD implementation which suffers a significant store forwarding stall penalty.

src/jit/codegenxarch.cpp
src/jit/morph.cpp
src/vm/jithelpers.cpp

index 3f05348..4820257 100644 (file)
@@ -8018,7 +8018,8 @@ void CodeGen::genIntToFloatCast(GenTreePtr treeNode)
     assert(!varTypeIsFloating(srcType) && varTypeIsFloating(dstType));
 
 #if !defined(_TARGET_64BIT_)
-    NYI_IF(varTypeIsLong(srcType), "Conversion from long to float");
+    // We expect morph to replace long to float/double casts with helper calls
+    noway_assert(!varTypeIsLong(srcType));
 #endif // !defined(_TARGET_64BIT_)
 
     // Since xarch emitter doesn't handle reporting gc-info correctly while casting away gc-ness we
index 00df17b..1423bc9 100644 (file)
@@ -360,8 +360,17 @@ GenTreePtr Compiler::fgMorphCast(GenTreePtr tree)
             oper = gtNewCastNode(TYP_LONG, oper, TYP_LONG);
             oper->gtFlags |= (tree->gtFlags & (GTF_OVERFLOW | GTF_EXCEPT | GTF_UNSIGNED));
             tree->gtFlags &= ~GTF_UNSIGNED;
+#ifndef LEGACY_BACKEND
+            return fgMorphCastIntoHelper(tree, CORINFO_HELP_LNG2DBL, oper);
+#endif
         }
     }
+#ifndef LEGACY_BACKEND
+    else if (((tree->gtFlags & GTF_UNSIGNED) == 0) && (srcType == TYP_LONG) && varTypeIsFloating(dstType))
+    {
+        return fgMorphCastIntoHelper(tree, CORINFO_HELP_LNG2DBL, oper);
+    }
+#endif
 #endif //_TARGET_XARCH_
     else if (varTypeIsGC(srcType) != varTypeIsGC(dstType))
     {
index 276c2d6..b578e6f 100644 (file)
@@ -513,7 +513,7 @@ HCIMPL1_V(double, JIT_ULng2Dbl, UINT64 val)
 HCIMPLEND
 
 /*********************************************************************/
-// needed for ARM
+// needed for ARM and RyuJIT-x86
 HCIMPL1_V(double, JIT_Lng2Dbl, INT64 val)
 {
     FCALL_CONTRACT;