-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
On ARM32 VSD calls and R2R calls pass an indirection cell in R4 which is a callee-saved register. This is unlike other platforms where a volatile register is used instead. Because of this there has to be special handling in getKillSetForCall, but currently we only have such handling for VSD calls:
runtime/src/coreclr/jit/lsrabuild.cpp
Lines 895 to 900 in 9dfbc5b
| #ifdef TARGET_ARM | |
| if (call->IsVirtualStub()) | |
| { | |
| killMask |= compiler->virtualStubParamInfo->GetRegMask(); | |
| } | |
| #else // !TARGET_ARM |
We work around this issue in morph by locking in the register requirement on the node itself and marking the constant as no-CSE:
runtime/src/coreclr/jit/morph.cpp
Lines 2113 to 2120 in 9dfbc5b
| indirectCellAddress->SetRegNum(REG_R2R_INDIRECT_PARAM); | |
| #ifdef TARGET_ARM | |
| // Issue #xxxx : Don't attempt to CSE this constant on ARM32 | |
| // | |
| // This constant has specific register requirements, and LSRA doesn't currently correctly | |
| // handle them when the value is in a CSE'd local. | |
| indirectCellAddress->SetDoNotCSE(); | |
| #endif // TARGET_ARM |
When I have tried fixing the problem and removing the morph workaround I have seen som large-ish crossgen ARM regressions, so some more investigation is needed.
category:correctness
theme:register-allocator