@@ -2232,6 +2232,10 @@ void emitter::emitCreatePlaceholderIG(insGroupPlaceholderType igType,
22322232        emitCurIG->igFlags  &= ~IGF_PROPAGATE_MASK;
22332233    }
22342234
2235+     //  since we have emitted a placeholder, the last ins is not longer the last.
2236+     emitLastIns   = nullptr ;
2237+     emitLastInsIG = nullptr ;
2238+ 
22352239#ifdef  DEBUG
22362240    if  (emitComp->verbose )
22372241    {
@@ -2895,10 +2899,36 @@ bool emitter::emitNoGChelper(CORINFO_METHOD_HANDLE methHnd)
28952899 *  Mark the current spot as having a label. 
28962900 */  
28972901
2898- void * emitter::emitAddLabel (VARSET_VALARG_TP    GCvars,
2899-                             regMaskTP           gcrefRegs,
2900-                             regMaskTP byrefRegs DEBUG_ARG (BasicBlock* block))
2902+ void * emitter::emitAddLabel (VARSET_VALARG_TP GCvars, regMaskTP gcrefRegs, regMaskTP byrefRegs, BasicBlock* prevBlock)
29012903{
2904+     if  (emitLastInsIsCallWithGC ())
2905+     {
2906+         //  We have just emitted a call that can do GC and conservatively recorded what is alive after the call.
2907+         //  Now we see that the next instruction may be reachable by a branch with a different liveness.
2908+         //  We want to maintain the invariant that the GC info at IP after a GC-capable call is the same
2909+         //  regardless how it is reached.
2910+         //  One way to fix this is to fish out the call instruction and patch its GC info, but we must be
2911+         //  certain that the current IP is indeed reachable after the call.
2912+         //  Another way it to add an instruction (NOP or BRK) after the call.
2913+         if  (emitThisGCrefRegs != gcrefRegs || emitThisByrefRegs != byrefRegs ||
2914+             !VarSetOps::Equal (emitComp, emitThisGCrefVars, GCvars))
2915+         {
2916+             if  (prevBlock->KindIs (BBJ_THROW))
2917+             {
2918+                 emitIns (INS_BREAKPOINT);
2919+             }
2920+             else 
2921+             {
2922+                 //  other block kinds should emit something at the end that is not a call.
2923+                 assert (prevBlock->KindIs (BBJ_ALWAYS));
2924+                 //  CONSIDER: We could patch up the previous call instruction with new GC info instead.
2925+                 //            But that will need to be coordinated with how the GC info vor variables is used.
2926+                 //            We currently apply that info to the instruction before the call. It may need to change.
2927+                 emitIns (INS_nop);
2928+             }
2929+         }
2930+     }
2931+ 
29022932    /*  Create a new IG if the current one is non-empty */ 
29032933
29042934    if  (emitCurIGnonEmpty ())
@@ -3663,6 +3693,7 @@ emitter::instrDesc* emitter::emitNewInstrCallInd(int              argCnt,
36633693
36643694        /*  Make sure we didn't waste space unexpectedly */ 
36653695        assert (!id->idIsLargeCns ());
3696+         id->idSetIsCall ();
36663697
36673698#ifdef  TARGET_XARCH
36683699        /*  Store the displacement and make sure the value fit */ 
@@ -3742,6 +3773,7 @@ emitter::instrDesc* emitter::emitNewInstrCallDir(int              argCnt,
37423773
37433774        /*  Make sure we didn't waste space unexpectedly */ 
37443775        assert (!id->idIsLargeCns ());
3776+         id->idSetIsCall ();
37453777
37463778        /*  Save the live GC registers in the unused register fields */ 
37473779        assert ((gcrefRegs & RBM_CALLEE_TRASH) == 0 );
@@ -8754,6 +8786,16 @@ void emitter::emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE* addr)
87548786    emitThisGCrefVset = true ;
87558787}
87568788
8789+ /* ****************************************************************************
8790+  * 
8791+  *  Last emitted instruction is a call and it is not a NoGC call. 
8792+  */  
8793+ 
8794+ bool  emitter::emitLastInsIsCallWithGC ()
8795+ {
8796+     return  emitLastIns != nullptr  && emitLastIns->idIsCall () && !emitLastIns->idIsNoGC ();
8797+ }
8798+ 
87578799/* ****************************************************************************
87588800 * 
87598801 *  Record a call location for GC purposes (we know that this is a method that 
0 commit comments