From d0dbb2995ebaa59a836fe4dad8e1a186d13b37d6 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Tue, 18 Sep 2018 15:40:32 -0700 Subject: [PATCH] Fix MultiReg methods on GenTree The Copy/Reload case was not being handled for 64-bit targets with multireg ops. Also, the methods `IsMultiRegNode`, `GetMultiRegCount`, `GetRegByIndex` and `GetRegTypeByIndex` should be in sync. Fix dotnet/coreclr#20031 Commit migrated from https://github.com/dotnet/coreclr/commit/8194ab91d6d535b15fe46877bbe2cc650595f334 --- src/coreclr/src/jit/gentree.h | 53 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index 12bb9aa..dbb5a75 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -6023,20 +6023,39 @@ inline bool GenTree::IsMultiRegCall() const // // Return Value: // Returns true if this GenTree is a multi-reg node. +// +// Notes: +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline bool GenTree::IsMultiRegNode() const { +#if FEATURE_MULTIREG_RET if (IsMultiRegCall()) { return true; } +#if FEATURE_ARG_SPLIT + if (OperIsPutArgSplit()) + { + return true; + } +#endif + #if !defined(_TARGET_64BIT_) - if (OperIsMultiRegOp() || OperIsPutArgSplit() || (gtOper == GT_COPY)) + if (OperIsMultiRegOp()) { return true; } #endif + if (OperIs(GT_COPY, GT_RELOAD)) + { + return true; + } +#endif // FEATURE_MULTIREG_RET return false; } //----------------------------------------------------------------------------------- @@ -6047,8 +6066,15 @@ inline bool GenTree::IsMultiRegNode() const // // Return Value: // Returns the number of registers defined by this node. +// +// Notes: +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline unsigned GenTree::GetMultiRegCount() { +#if FEATURE_MULTIREG_RET if (IsMultiRegCall()) { return AsCall()->GetReturnTypeDesc()->GetReturnRegCount(); @@ -6060,16 +6086,19 @@ inline unsigned GenTree::GetMultiRegCount() return AsPutArgSplit()->gtNumRegs; } #endif + #if !defined(_TARGET_64BIT_) if (OperIsMultiRegOp()) { return AsMultiRegOp()->GetRegCount(); } +#endif + if (OperIs(GT_COPY, GT_RELOAD)) { return AsCopyOrReload()->GetRegCount(); } -#endif +#endif // FEATURE_MULTIREG_RET assert(!"GetMultiRegCount called with non-multireg node"); return 1; } @@ -6084,12 +6113,20 @@ inline unsigned GenTree::GetMultiRegCount() // Return Value: // The register, if any, assigned to this index for this node. // +// Notes: +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline regNumber GenTree::GetRegByIndex(int regIndex) { if (regIndex == 0) { return gtRegNum; } + +#if FEATURE_MULTIREG_RET + if (IsMultiRegCall()) { return AsCall()->GetRegNumByIdx(regIndex); @@ -6106,11 +6143,14 @@ inline regNumber GenTree::GetRegByIndex(int regIndex) { return AsMultiRegOp()->GetRegNumByIdx(regIndex); } +#endif + if (OperIs(GT_COPY, GT_RELOAD)) { return AsCopyOrReload()->GetRegNumByIdx(regIndex); } -#endif +#endif // FEATURE_MULTIREG_RET + assert(!"Invalid regIndex for GetRegFromMultiRegNode"); return REG_NA; } @@ -6129,8 +6169,13 @@ inline regNumber GenTree::GetRegByIndex(int regIndex) // This must be a multireg node that is *not* a copy or reload (which must retrieve the // type from its source), and 'regIndex' must be a valid index for this node. // +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline var_types GenTree::GetRegTypeByIndex(int regIndex) { +#if FEATURE_MULTIREG_RET if (IsMultiRegCall()) { return AsCall()->AsCall()->GetReturnTypeDesc()->GetReturnRegType(regIndex); @@ -6148,6 +6193,8 @@ inline var_types GenTree::GetRegTypeByIndex(int regIndex) return AsMultiRegOp()->GetRegType(regIndex); } #endif + +#endif // FEATURE_MULTIREG_RET assert(!"Invalid node type for GetRegTypeByIndex"); return TYP_UNDEF; } -- 2.7.4