summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2017-10-05 22:31:17 -0700
committerGitHub <noreply@github.com>2017-10-05 22:31:17 -0700
commit60374d77dacc076b30673c37ddace25d12cabcd9 (patch)
tree454c63573966c7ef3048d34dbc590770a1760f22 /src
parent6ef58bae7c5ffc966cae00d37906769e66b98485 (diff)
parent045492911eec18308c360e70f08de3baee13c199 (diff)
downloadcoreclr-60374d77dacc076b30673c37ddace25d12cabcd9.tar.gz
coreclr-60374d77dacc076b30673c37ddace25d12cabcd9.tar.bz2
coreclr-60374d77dacc076b30673c37ddace25d12cabcd9.zip
Merge pull request #14253 from wateret/fix-14251
[RyuJIT/armel] Fix regression
Diffstat (limited to 'src')
-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 5ca06a0e51..30695d86c5 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -7124,7 +7124,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 60d9080dc6..1e137ce0e9 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -6116,7 +6116,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: