Allow early prop to undertand how R2R creates arrays (#42831)
authornathan-moore <nathanmoore424@gmail.com>
Thu, 7 Jan 2021 22:57:58 +0000 (17:57 -0500)
committerGitHub <noreply@github.com>
Thu, 7 Jan 2021 22:57:58 +0000 (14:57 -0800)
src/coreclr/jit/earlyprop.cpp
src/coreclr/jit/importer.cpp

index 1b63682..adf669f 100644 (file)
@@ -70,6 +70,8 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc
 {
     assert(tree != nullptr);
 
+    GenTree* arrayLength = nullptr;
+
     if (tree->OperGet() == GT_CALL)
     {
         GenTreeCall* call = tree->AsCall();
@@ -81,17 +83,28 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_VC) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8))
             {
+                // This is an array allocation site. Grab the array length node.
+                arrayLength = gtArgEntryByArgNum(call, 1)->GetNode();
+            }
+            else if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1))
+            {
+                // On arm when compiling on certain platforms for ready to run, a handle will be
+                // inserted before the length. To handle this case, we will grab the last argument
+                // as that's always the length. See fgInitArgInfo for where the handle is inserted.
+                int arrLenArgNum = call->fgArgInfo->ArgCount() - 1;
+                arrayLength      = gtArgEntryByArgNum(call, arrLenArgNum)->GetNode();
+            }
 #ifdef DEBUG
+            if (arrayLength != nullptr)
+            {
                 optCheckFlagsAreSet(OMF_HAS_NEWARRAY, "OMF_HAS_NEWARRAY", BBF_HAS_NEWARRAY, "BBF_HAS_NEWARRAY", tree,
                                     block);
-#endif
-                // This is an array allocation site. Grab the array length node.
-                return gtArgEntryByArgNum(call, 1)->GetNode();
             }
+#endif
         }
     }
 
-    return nullptr;
+    return arrayLength;
 }
 
 //-----------------------------------------------------------------------------
@@ -344,7 +357,7 @@ GenTree* Compiler::optEarlyPropRewriteTree(GenTree* tree, LocalNumberToNullCheck
     if (actualVal != nullptr)
     {
         assert(propKind == optPropKind::OPK_ARRAYLEN);
-        assert(actualVal->IsCnsIntOrI());
+        assert(actualVal->IsCnsIntOrI() && !actualVal->AsIntCon()->IsIconHandle());
         assert(actualVal->GetNodeSize() == TREE_NODE_SZ_SMALL);
 
         ssize_t actualConstVal = actualVal->AsIntCon()->IconValue();
index cf114a6..078a745 100644 (file)
@@ -3522,7 +3522,7 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig)
         }
 
         //
-        // Make sure that the number of elements look valid.
+        // This optimization is only valid for a constant array size.
         //
         if (arrayLengthNode->gtOper != GT_CNS_INT)
         {