From: Sergey Andreenko Date: Fri, 15 Dec 2017 02:17:53 +0000 (-0800) Subject: [RyuJit][Armel] Do not lose type information (#15449) X-Git-Tag: accepted/tizen/base/20180629.140029~317 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9576b24e491b8a28442dec2696b862dcb29ddc25;p=platform%2Fupstream%2Fcoreclr.git [RyuJit][Armel] Do not lose type information (#15449) * Do not lose type information fgMorphMultiregStructArg could lose type information when replaced smth like this: GT_OBJ - TYP_STRUCT <== arg + GT_ADDR - TYP_I_IMPL + + GT_LCL_VAR - TYP_BLK <== argValue * Move the test to pri0 to test in ci. * add an assert * add the test to the arm list * make the optimization only if struct handlers match. * format job * fix for the unoptimized case. * check that we have addr node. * change the reason to lvaSetVarDoNotEnregister --- diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 73883e5..b5d2e8a 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -4963,11 +4963,18 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f objClass = argObj->gtClass; structSize = info.compCompHnd->getClassSize(objClass); - // If we have a GT_OBJ of a GT_ADDR then we set argValue to the child node of the GT_ADDR - // - if (argObj->gtOp1->OperGet() == GT_ADDR) + // If we have a GT_OBJ of a GT_ADDR then we set argValue to the child node of the GT_ADDR. + GenTree* op1 = argObj->gtOp1; + if (op1->OperGet() == GT_ADDR) { - argValue = argObj->gtOp1->gtOp.gtOp1; + GenTree* underlyingTree = op1->gtOp.gtOp1; + + // Only update to the same type. + if ((underlyingTree->TypeGet() == argValue->TypeGet()) && + (objClass == gtGetStructHandleIfPresent(underlyingTree))) + { + argValue = underlyingTree; + } } } else if (arg->OperGet() == GT_LCL_VAR) @@ -5342,6 +5349,19 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f GenTreePtr baseAddr = argObj->gtOp1; var_types addrType = baseAddr->TypeGet(); + if (baseAddr->OperGet() == GT_ADDR) + { + GenTree* addrTaken = baseAddr->gtOp.gtOp1; + if (addrTaken->IsLocal()) + { + GenTreeLclVarCommon* varNode = addrTaken->AsLclVarCommon(); + unsigned varNum = varNode->gtLclNum; + // We access non-struct type (for example, long) as a struct type. + // Make sure lclVar lives on stack to make sure its fields are accessible by address. + lvaSetVarDoNotEnregister(varNum DEBUGARG(DNER_LocalField)); + } + } + // Create a new tree for 'arg' // replace the existing LDOBJ(EXPR) // with a FIELD_LIST(IND(EXPR), FIELD_LIST(IND(EXPR+8), nullptr) ...) diff --git a/tests/src/JIT/Methodical/tailcall/_il_dbgtest_3b.ilproj b/tests/src/JIT/Methodical/tailcall/_il_dbgtest_3b.ilproj index 114e9e8..fb6053c 100644 --- a/tests/src/JIT/Methodical/tailcall/_il_dbgtest_3b.ilproj +++ b/tests/src/JIT/Methodical/tailcall/_il_dbgtest_3b.ilproj @@ -10,7 +10,6 @@ Exe {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} ..\..\ - 1 diff --git a/tests/testsRunningInsideARM.txt b/tests/testsRunningInsideARM.txt index de33d2e..507bfc4 100644 --- a/tests/testsRunningInsideARM.txt +++ b/tests/testsRunningInsideARM.txt @@ -1,5 +1,6 @@ JIT/Directed/coverage/importer/ldelemnullarr2/ JIT/Methodical/Coverage/b39946/ +JIT/Methodical/tailcall/_il_dbgtest_3b/ JIT/Regression/CLR-x86-JIT/V1-M09.5-PDC/b26863/b26863/ JIT/Regression/CLR-x86-JIT/V1-M09.5-PDC/b28037/b28037/ JIT/Regression/CLR-x86-JIT/V1-M09.5-PDC/b29068/b29068/