summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanjoung Lee <hanjoung.lee@samsung.com>2017-09-29 18:50:16 +0900
committerHanjoung Lee <hanjoung.lee@samsung.com>2017-10-05 20:29:28 +0900
commit045492911eec18308c360e70f08de3baee13c199 (patch)
tree98be5b1cdb43d7efd138ea740e2de043e7ba7dc8
parent076a61ef2eb3baf69182139f36b948f104e3b740 (diff)
downloadcoreclr-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.cpp2
-rw-r--r--src/jit/gentree.h3
-rw-r--r--src/jit/lower.cpp29
-rw-r--r--src/jit/lsra.cpp6
-rw-r--r--src/jit/lsraarm.cpp13
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: