Fix arm32 stub indirect tailcall
authorBruce Forstall <brucefo@microsoft.com>
Wed, 22 Nov 2017 23:39:49 +0000 (15:39 -0800)
committerBruce Forstall <brucefo@microsoft.com>
Wed, 22 Nov 2017 23:39:49 +0000 (15:39 -0800)
ARM has code in fgMorphTailCall to insert a level of indirection
for the call address of a stub indirect tailcall. Then, LowerVirtualStubCall
inserts another level of indirection. Only one is necessary/required,
so stop inserting the second indirection in LowerVirtualStubCall.

Fixes #15152, #14862 (all current TailcallStress=1 and JitStress=1 failures).

src/jit/lower.cpp

index 9d63c4b5224200f10a8b1be18a9fe8295d949021..df60d0253894afac7f279df9c02edc0ef570519e 100644 (file)
@@ -4138,12 +4138,27 @@ GenTree* Lowering::LowerVirtualStubCall(GenTreeCall* call)
         // fgMorphArgs will have created trees to pass the address in VirtualStubParam.reg.
         // All we have to do here is add an indirection to generate the actual call target.
 
-        GenTree* ind = Ind(call->gtCallAddr);
+        GenTree* ind;
+
+#ifdef _TARGET_ARM_
+        // For ARM, fgMorphTailCall has already made gtCallAddr a GT_IND for virtual stub tail calls.
+        // (When we eliminate LEGACY_BACKEND maybe we can eliminate this asymmetry?)
+        if (call->IsTailCallViaHelper())
+        {
+            ind = call->gtCallAddr;
+            assert(ind->gtOper == GT_IND);
+        }
+        else
+#endif // _TARGET_ARM_
+        {
+            ind = Ind(call->gtCallAddr);
+            BlockRange().InsertAfter(call->gtCallAddr, ind);
+            call->gtCallAddr = ind;
+        }
+
         ind->gtFlags |= GTF_IND_REQ_ADDR_IN_REG;
 
-        BlockRange().InsertAfter(call->gtCallAddr, ind);
         ContainCheckIndir(ind->AsIndir());
-        call->gtCallAddr = ind;
     }
     else
     {