diff options
author | Hanjoung Lee <hanjoung.lee@samsung.com> | 2017-09-29 18:50:16 +0900 |
---|---|---|
committer | Hanjoung Lee <hanjoung.lee@samsung.com> | 2017-10-05 20:29:28 +0900 |
commit | 045492911eec18308c360e70f08de3baee13c199 (patch) | |
tree | 98be5b1cdb43d7efd138ea740e2de043e7ba7dc8 | |
parent | 076a61ef2eb3baf69182139f36b948f104e3b740 (diff) | |
download | coreclr-045492911eec18308c360e70f08de3baee13c199.tar.gz coreclr-045492911eec18308c360e70f08de3baee13c199.tar.bz2 coreclr-045492911eec18308c360e70f08de3baee13c199.zip |
[RyuJIT/armel] Fix regression
Fix calling a function passing double-type stack arguments.
Fix #14251
-rw-r--r-- | src/jit/gentree.cpp | 2 | ||||
-rw-r--r-- | src/jit/gentree.h | 3 | ||||
-rw-r--r-- | src/jit/lower.cpp | 29 | ||||
-rw-r--r-- | src/jit/lsra.cpp | 6 | ||||
-rw-r--r-- | src/jit/lsraarm.cpp | 13 |
5 files changed, 40 insertions, 13 deletions
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index c3fbc271e6..591cf67b53 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -7117,7 +7117,7 @@ GenTreePtr Compiler::gtNewBitCastNode(var_types type, GenTreePtr arg) assert(arg != nullptr); GenTreePtr node = nullptr; -#if !defined(LEGACY_BACKEND) && defined(ARM_SOFTFP) +#if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_) // A BITCAST could be a MultiRegOp on armel since we could move a double register to two int registers. node = new (this, GT_PUTARG_REG) GenTreeMultiRegOp(GT_BITCAST, type, arg, nullptr); #else diff --git a/src/jit/gentree.h b/src/jit/gentree.h index e8803e0e1d..8ad53355e4 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -6060,7 +6060,8 @@ inline bool GenTree::IsMultiRegNode() const } #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_) - if (gtOper == GT_MUL_LONG || gtOper == GT_PUTARG_REG || gtOper == GT_BITCAST || OperIsPutArgSplit()) + if (gtOper == GT_MUL_LONG || gtOper == GT_PUTARG_REG || gtOper == GT_BITCAST || gtOper == GT_COPY || + OperIsPutArgSplit()) { return true; } diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp index 18cf09a1ad..9ecce38c15 100644 --- a/src/jit/lower.cpp +++ b/src/jit/lower.cpp @@ -765,7 +765,7 @@ void Lowering::ReplaceArgWithPutArgOrCopy(GenTree** argSlot, GenTree* putArgOrCo { assert(argSlot != nullptr); assert(*argSlot != nullptr); - assert(putArgOrCopy->OperIsPutArg() || putArgOrCopy->OperIs(GT_BITCAST)); + assert(putArgOrCopy->OperIsPutArg() || putArgOrCopy->OperIs(GT_BITCAST) || putArgOrCopy->OperIs(GT_COPY)); GenTree* arg = *argSlot; @@ -1298,18 +1298,27 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg) { var_types intType = (type == TYP_DOUBLE) ? TYP_LONG : TYP_INT; - GenTreePtr intArg = comp->gtNewBitCastNode(intType, arg); - intArg->gtRegNum = info->regNum; + GenTreePtr intArg; + if (isReg) + { + intArg = comp->gtNewBitCastNode(intType, arg); + intArg->gtRegNum = info->regNum; #ifdef ARM_SOFTFP - if (intType == TYP_LONG) + if (intType == TYP_LONG) + { + assert(info->numRegs == 2); + regNumber regNext = REG_NEXT(info->regNum); + // double type arg regs can only be either r0:r1 or r2:r3. + assert((info->regNum == REG_R0 && regNext == REG_R1) || + (info->regNum == REG_R2 && regNext == REG_R3)); + intArg->AsMultiRegOp()->gtOtherReg = regNext; + } +#endif // ARM_SOFTFP + } + else { - assert(info->numRegs == 2); - regNumber regNext = REG_NEXT(info->regNum); - // double type arg regs can only be either r0:r1 or r2:r3. - assert((info->regNum == REG_R0 && regNext == REG_R1) || (info->regNum == REG_R2 && regNext == REG_R3)); - intArg->AsMultiRegOp()->gtOtherReg = regNext; + intArg = new (comp, GT_COPY) GenTreeCopyOrReload(GT_COPY, intType, arg); } -#endif // ARM_SOFTFP info->node = intArg; ReplaceArgWithPutArgOrCopy(ppArg, intArg); diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp index a59af282e6..385ce9f87e 100644 --- a/src/jit/lsra.cpp +++ b/src/jit/lsra.cpp @@ -140,6 +140,12 @@ void lsraAssignRegToTree(GenTreePtr tree, regNumber reg, unsigned regIdx) GenTreeMultiRegOp* mul = tree->AsMultiRegOp(); mul->gtOtherReg = reg; } + else if (tree->OperGet() == GT_COPY) + { + assert(regIdx == 1); + GenTreeCopyOrReload* copy = tree->AsCopyOrReload(); + copy->gtOtherRegs[0] = (regNumberSmall)reg; + } else if (tree->OperGet() == GT_PUTARG_SPLIT) { GenTreePutArgSplit* putArg = tree->AsPutArgSplit(); diff --git a/src/jit/lsraarm.cpp b/src/jit/lsraarm.cpp index f35a23a72b..3566be0623 100644 --- a/src/jit/lsraarm.cpp +++ b/src/jit/lsraarm.cpp @@ -690,7 +690,18 @@ void LinearScan::TreeNodeInfoInit(GenTree* tree) case GT_COPY: info->srcCount = 1; - assert(info->dstCount == 1); +#ifdef ARM_SOFTFP + // This case currently only occurs for double types that are passed as TYP_LONG; + // actual long types would have been decomposed by now. + if (tree->TypeGet() == TYP_LONG) + { + info->dstCount = 2; + } + else +#endif + { + assert(info->dstCount == 1); + } break; case GT_PUTARG_SPLIT: |