[Arm64] Add Floor/Ceiling intrinsics (#14132)
authorSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>
Fri, 22 Sep 2017 23:59:22 +0000 (19:59 -0400)
committerBruce Forstall <brucefo@microsoft.com>
Fri, 22 Sep 2017 23:59:22 +0000 (16:59 -0700)
* [Arm64] Add Floor/Ceiling intrinsics

* Templatize emitActualTypeSize

src/jit/codegenarmarch.cpp
src/jit/emit.h
src/jit/importer.cpp
src/jit/lsraarm64.cpp
src/jit/valuenum.cpp

index 9b16fad..0c609b2 100644 (file)
@@ -445,7 +445,7 @@ void CodeGen::genIntrinsic(GenTreePtr treeNode)
     assert(varTypeIsFloating(srcNode));
     assert(srcNode->TypeGet() == treeNode->TypeGet());
 
-    // Right now only Abs/Round/Sqrt are treated as math intrinsics.
+    // Right now only Abs/Ceiling/Floor/Round/Sqrt are treated as math intrinsics.
     //
     switch (treeNode->gtIntrinsic.gtIntrinsicId)
     {
@@ -454,6 +454,17 @@ void CodeGen::genIntrinsic(GenTreePtr treeNode)
             getEmitter()->emitInsBinary(INS_ABS, emitTypeSize(treeNode), treeNode, srcNode);
             break;
 
+#ifdef _TARGET_ARM64_
+        case CORINFO_INTRINSIC_Ceiling:
+            genConsumeOperands(treeNode->AsOp());
+            getEmitter()->emitInsBinary(INS_frintp, emitActualTypeSize(treeNode), treeNode, srcNode);
+            break;
+
+        case CORINFO_INTRINSIC_Floor:
+            genConsumeOperands(treeNode->AsOp());
+            getEmitter()->emitInsBinary(INS_frintm, emitActualTypeSize(treeNode), treeNode, srcNode);
+            break;
+#endif
         case CORINFO_INTRINSIC_Round:
             NYI_ARM("genIntrinsic for round - not implemented yet");
             genConsumeOperands(treeNode->AsOp());
index a9dc076..8c2b825 100644 (file)
@@ -2382,11 +2382,12 @@ inline emitAttr emitTypeSize(T type)
 
 extern const unsigned short emitTypeActSz[TYP_COUNT];
 
-inline emitAttr emitActualTypeSize(var_types type)
+template <class T>
+inline emitAttr emitActualTypeSize(T type)
 {
-    assert(type < TYP_COUNT);
-    assert(emitTypeActSz[type] > 0);
-    return (emitAttr)emitTypeActSz[type];
+    assert(TypeGet(type) < TYP_COUNT);
+    assert(emitTypeActSz[TypeGet(type)] > 0);
+    return (emitAttr)emitTypeActSz[TypeGet(type)];
 }
 
 /*****************************************************************************
index ddee0ab..e10ae6a 100644 (file)
@@ -18701,6 +18701,8 @@ bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId)
         case CORINFO_INTRINSIC_Sqrt:
         case CORINFO_INTRINSIC_Abs:
         case CORINFO_INTRINSIC_Round:
+        case CORINFO_INTRINSIC_Floor:
+        case CORINFO_INTRINSIC_Ceiling:
             return true;
 
         default:
index e39c0d9..0b6891a 100644 (file)
@@ -260,9 +260,9 @@ void LinearScan::TreeNodeInfoInit(GenTree* tree)
 
         case GT_INTRINSIC:
         {
-            // TODO-ARM64-NYI
-            // Right now only Abs/Round/Sqrt are treated as math intrinsics
             noway_assert((tree->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Abs) ||
+                         (tree->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Ceiling) ||
+                         (tree->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Floor) ||
                          (tree->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Round) ||
                          (tree->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Sqrt));
 
index e4990d6..473f0ce 100644 (file)
@@ -3514,6 +3514,12 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
                 case CORINFO_INTRINSIC_Abs:
                     res = fabs(arg0Val);
                     break;
+                case CORINFO_INTRINSIC_Ceiling:
+                    res = ceil(arg0Val);
+                    break;
+                case CORINFO_INTRINSIC_Floor:
+                    res = floor(arg0Val);
+                    break;
                 case CORINFO_INTRINSIC_Round:
                     res = FloatingPointUtils::round(arg0Val);
                     break;
@@ -3544,6 +3550,12 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
                 case CORINFO_INTRINSIC_Abs:
                     res = fabsf(arg0Val);
                     break;
+                case CORINFO_INTRINSIC_Ceiling:
+                    res = ceilf(arg0Val);
+                    break;
+                case CORINFO_INTRINSIC_Floor:
+                    res = floorf(arg0Val);
+                    break;
                 case CORINFO_INTRINSIC_Round:
                     res = FloatingPointUtils::round(arg0Val);
                     break;