Fix issue dotnet/coreclr#11447.
authorPat Gavlin <pagavlin@microsoft.com>
Mon, 8 May 2017 19:17:42 +0000 (12:17 -0700)
committerPat Gavlin <pagavlin@microsoft.com>
Mon, 8 May 2017 19:17:42 +0000 (12:17 -0700)
This issue was caused by the code for PInvoke frame initialization reading
from the stub argument register after it had been trashed by prior
instructions. This change fixes this issue by inserting the PInvoke
frame initialization at the beginning of the scratch block into which it
is inserted rather than at the end.

Note that a more correct fix here would be to represent the stub
argument as a lclVar rather than a physical register; that work is
tracked by dotnet/coreclr#11450.

Commit migrated from https://github.com/dotnet/coreclr/commit/673242edd0a0939e0e4cd22d6a217dbd9295ba00

src/coreclr/src/jit/lower.cpp

index 035f094..72dba4e 100644 (file)
@@ -2872,8 +2872,10 @@ void Lowering::InsertPInvokeMethodProlog()
     store->gtOp.gtOp1 = call;
     store->gtFlags |= GTF_VAR_DEF;
 
+    GenTree* const insertionPoint = firstBlockRange.FirstNonPhiOrCatchArgNode();
+
     comp->fgMorphTree(store);
-    firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, store));
+    firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, store));
     DISPTREERANGE(firstBlockRange, store);
 
 #if !defined(_TARGET_X86_) && !defined(_TARGET_ARM_)
@@ -2887,7 +2889,7 @@ void Lowering::InsertPInvokeMethodProlog()
         GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfCallSiteSP);
     storeSP->gtOp1 = PhysReg(REG_SPBASE);
 
-    firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, storeSP));
+    firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeSP));
     DISPTREERANGE(firstBlockRange, storeSP);
 
 #endif // !defined(_TARGET_X86_) && !defined(_TARGET_ARM_)
@@ -2903,7 +2905,7 @@ void Lowering::InsertPInvokeMethodProlog()
                                                    callFrameInfo.offsetOfCalleeSavedFP);
     storeFP->gtOp1 = PhysReg(REG_FPBASE);
 
-    firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, storeFP));
+    firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeFP));
     DISPTREERANGE(firstBlockRange, storeFP);
 #endif // !defined(_TARGET_ARM_)
 
@@ -2918,7 +2920,7 @@ void Lowering::InsertPInvokeMethodProlog()
         // Push a frame - if we are NOT in an IL stub, this is done right before the call
         // The init routine sets InlinedCallFrame's m_pNext, so we just set the thead's top-of-stack
         GenTree* frameUpd = CreateFrameLinkUpdate(PushFrame);
-        firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, frameUpd));
+        firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, frameUpd));
         DISPTREERANGE(firstBlockRange, frameUpd);
     }
 #endif // _TARGET_64BIT_