JIT: fix return type mismatch inline block for literal argument (#16966)
authorAndy Ayers <andya@microsoft.com>
Fri, 16 Mar 2018 15:07:30 +0000 (08:07 -0700)
committerGitHub <noreply@github.com>
Fri, 16 Mar 2018 15:07:30 +0000 (08:07 -0700)
When we inline a method that returns one of its arguments, we need to make sure
to apply the callee's view of the argument type.

We fixed this for arguments that are caller locals in #11218. This change applies
similar logic to handle the case where the caller passes a literal constant.

Closes #16944.

src/jit/importer.cpp

index 787d758..30faec2 100644 (file)
@@ -15819,6 +15819,8 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
 
             if (returnType != originalCallType)
             {
+                JITDUMP("Return type mismatch, have %s, needed %s\n", varTypeName(returnType),
+                        varTypeName(originalCallType));
                 compInlineResult->NoteFatal(InlineObservation::CALLSITE_RETURN_TYPE_MISMATCH);
                 return false;
             }
@@ -18670,6 +18672,17 @@ GenTree* Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, In
         op1 = gtCloneExpr(argInfo.argNode);
         PREFIX_ASSUME(op1 != nullptr);
         argInfo.argTmpNum = BAD_VAR_NUM;
+
+        // We may need to retype to ensure we match the callee's view of the type.
+        // Otherwise callee-pass throughs of arguments can create return type
+        // mismatches that block inlining.
+        //
+        // Note argument type mismatches that prevent inlining should
+        // have been caught in impInlineInitVars.
+        if (op1->TypeGet() != lclTyp)
+        {
+            op1->gtType = genActualType(lclTyp);
+        }
     }
     else if (argInfo.argIsLclVar && !argCanBeModified && !argInfo.argHasCallerLocalRef)
     {