Fix SIMD store to spilled multi-reg local (#37781)
authorCarol Eidt <carol.eidt@microsoft.com>
Fri, 12 Jun 2020 18:03:23 +0000 (11:03 -0700)
committerGitHub <noreply@github.com>
Fri, 12 Jun 2020 18:03:23 +0000 (11:03 -0700)
Fix #37761

src/coreclr/src/jit/codegenarm64.cpp
src/coreclr/src/jit/lsra.cpp
src/coreclr/src/jit/treelifeupdater.cpp

index 949f7cc..186998a 100644 (file)
@@ -1948,6 +1948,7 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* lclNode)
             assert(fieldVarDsc->TypeGet() == TYP_FLOAT);
             GetEmitter()->emitIns_R_R_I(INS_dup, emitTypeSize(TYP_FLOAT), varReg, operandReg, i);
         }
+        genProduceReg(lclNode);
     }
     else
     {
index df8e9dd..da44c59 100644 (file)
@@ -6547,10 +6547,13 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreeLclVar* treeNode, Ref
             assert(currentRefPosition->refType == RefTypeExpUse);
         }
     }
-    else if (spillAfter && !RefTypeIsUse(currentRefPosition->refType))
+    else if (spillAfter && !RefTypeIsUse(currentRefPosition->refType) &&
+             (!treeNode->IsMultiReg() || treeNode->gtGetOp1()->IsMultiRegNode()))
     {
         // In the case of a pure def, don't bother spilling - just assign it to the
         // stack.  However, we need to remember that it was spilled.
+        // We can't do this in the case of a multi-reg node with a non-multireg source as
+        // we need the register to extract into.
 
         assert(interval->isSpilled);
         varDsc->SetRegNum(REG_STK);
index 9b93ed7..e9ba11f 100644 (file)
@@ -299,8 +299,11 @@ void TreeLifeUpdater<ForCodeGen>::UpdateLifeVar(GenTree* tree)
                         compiler->codeGen->genUpdateVarReg(fldVarDsc, tree, i);
                     }
                     compiler->codeGen->genUpdateRegLife(fldVarDsc, isBorn, isFieldDying DEBUGARG(tree));
+                    // If this was marked for spill, genProduceReg should already have spilled it.
+                    assert(!spill);
                 }
             }
+            spill = false;
         }
         else if (varDsc->lvPromoted)
         {