summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2016-05-18 10:33:28 -0700
committerBruce Forstall <brucefo@microsoft.com>2016-05-18 10:33:28 -0700
commitce8e7e3a0d6ad3dd34a8b3487c8068e49c6b45e0 (patch)
treeaba17ec49f0ba939bc66696757f208e4bd43d4cf
parent7d78bb285816c69f39c016950d3add07f650483e (diff)
downloadcoreclr-ce8e7e3a0d6ad3dd34a8b3487c8068e49c6b45e0.tar.gz
coreclr-ce8e7e3a0d6ad3dd34a8b3487c8068e49c6b45e0.tar.bz2
coreclr-ce8e7e3a0d6ad3dd34a8b3487c8068e49c6b45e0.zip
Rollback CS#1603899 that led to a JIT assert ngen'ing System.Windows.Forms.dll
==================== 007551: Merge pull request #1241 from mikedn/modopt Extend the DIV/MOD dividend into RDX:RAX only if needed ==================== Assert failure(PID 33656 [0x00008378], Thread: 17792 [0x4580]): Assertion failed 'addr->OperIsAddrMode() || (addr->IsCnsIntOrI() && addr->isContained()) || !addr->isContained()' in 'System.Windows.Forms.CheckedListBox:OnDrawItem(ref):this' (IL size 1216) File: e:\dd\projectk\src\ndp\clr\src\jit\emitxarch.cpp Line: 2698 Image: C:\Windows\Microsoft.NET\Framework64\v4.0.rb1605209\mscorsvw.exe The tree: ***** BB41, stmt 82 (embedded) ( 6, 8) [003723] ------------ * stmtExpr void (embedded) (IL 0x109... ???) N1045 ( 3, 2) [000115] ------------ | /--* lclVar ref V00 this u:2 REG rcx $80 N1047 ( 1, 4) [002642] ------------ | +--* const long 344 field offset Fseq[idealCheckSize] REG NA $10b N1049 ( 4, 6) [002643] -------N---- | /--* + byref REG NA $356 N1051 ( 6, 8) [000116] ----GO------ | /--* indir int REG rcx <l:$685, c:$2ef> N1053 ( 6, 8) [003669] DA--GO------ \--* st.lclVar int V172 cse1 rcx REG rcx RV During codegen: Generating BB41, stmt 71 Holding variables: [rbx rsi rdi r12-r15] Generating: N1043 ( 3, 2) [000114] ------------ * lclVar int V05 loc3 u:3 r12 (last use) REG r12 RV $31a Generating: N1045 ( 3, 2) [000115] ------------ * lclVar ref V00 this u:2 REG rcx $80 IN00db: mov rcx, gword ptr [V00 rbp+10H] GC regs: 00000040 {rsi} => 00000042 {rcx rsi} Generating: N1047 ( 1, 4) [002642] ------------ * const long 344 field offset Fseq[idealCheckSize] REG NA $10b Generating: N1049 ( 4, 6) [002643] -------N---- * + byref REG NA $356 Generating: N1051 ( 6, 8) [000116] ----GO------ * indir int REG rcx <l:$685, c:$2ef> ... assert ... (This is rollback #2: the TFS/GitHub mirror unfortunately undid rollback CS#1605814 with CS#1605840. This change should avoid that problem.) [tfs-changeset: 1605917]
-rw-r--r--src/jit/codegenarm64.cpp112
-rw-r--r--src/jit/codegenlinear.h2
-rw-r--r--src/jit/codegenxarch.cpp163
-rw-r--r--src/jit/lower.cpp202
-rw-r--r--src/jit/lower.h2
-rw-r--r--src/jit/lowerarm64.cpp1
-rw-r--r--src/jit/lowerxarch.cpp25
-rw-r--r--src/jit/morph.cpp2
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/DivConst.cs423
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/DivConst.csproj43
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/ModConst.cs427
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/ModConst.csproj43
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/UDivConst.cs219
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/UDivConst.csproj43
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/UModConst.cs224
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/UModConst.csproj43
16 files changed, 285 insertions, 1689 deletions
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index 574e438a70..18587bf3e6 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -3365,6 +3365,118 @@ CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
}
}
+
+// Generate code for division (or mod) by power of two
+// or negative powers of two. (meaning -1 * a power of two, not 2^(-1))
+// Op2 must be a contained integer constant.
+void
+CodeGen::genCodeForPow2Div(GenTreeOp* tree)
+{
+#if 0
+ GenTree *dividend = tree->gtOp.gtOp1;
+ GenTree *divisor = tree->gtOp.gtOp2;
+ genTreeOps oper = tree->OperGet();
+ emitAttr size = emitTypeSize(tree);
+ emitter *emit = getEmitter();
+ regNumber targetReg = tree->gtRegNum;
+ var_types targetType = tree->TypeGet();
+
+ bool isSigned = oper == GT_MOD || oper == GT_DIV;
+
+ // precondition: extended dividend is in RDX:RAX
+ // which means it is either all zeros or all ones
+
+ noway_assert(divisor->isContained());
+ GenTreeIntConCommon* divImm = divisor->AsIntConCommon();
+ int64_t imm = divImm->IconValue();
+ ssize_t abs_imm = abs(imm);
+ noway_assert(isPow2(abs_imm));
+
+
+ if (isSigned)
+ {
+ if (imm == 1)
+ {
+ if (targetReg != REG_RAX)
+ inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
+
+ return;
+ }
+
+ if (abs_imm == 2)
+ {
+ if (oper == GT_MOD)
+ {
+ emit->emitIns_R_I(INS_and, size, REG_RAX, 1); // result is 0 or 1
+ // xor with rdx will flip all bits if negative
+ emit->emitIns_R_R(INS_xor, size, REG_RAX, REG_RDX); // 111.11110 or 0
+ }
+ else
+ {
+ assert(oper == GT_DIV);
+ // add 1 if it's negative
+ emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
+ }
+ }
+ else
+ {
+ // add imm-1 if negative
+ emit->emitIns_R_I(INS_and, size, REG_RDX, abs_imm - 1);
+ emit->emitIns_R_R(INS_add, size, REG_RAX, REG_RDX);
+ }
+
+ if (oper == GT_DIV)
+ {
+ unsigned shiftAmount = genLog2(unsigned(abs_imm));
+ inst_RV_SH(INS_sar, size, REG_RAX, shiftAmount);
+
+ if (imm < 0)
+ {
+ emit->emitIns_R(INS_neg, size, REG_RAX);
+ }
+ }
+ else
+ {
+ assert(oper == GT_MOD);
+ if (abs_imm > 2)
+ {
+ emit->emitIns_R_I(INS_and, size, REG_RAX, abs_imm - 1);
+ }
+ // RDX contains 'imm-1' if negative
+ emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
+ }
+
+ if (targetReg != REG_RAX)
+ {
+ inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
+ }
+ }
+ else
+ {
+ assert (imm > 0);
+
+ if (targetReg != dividend->gtRegNum)
+ {
+ inst_RV_RV(INS_mov, targetReg, dividend->gtRegNum, targetType);
+ }
+
+ if (oper == GT_UDIV)
+ {
+ inst_RV_SH(INS_shr, size, targetReg, genLog2(unsigned(imm)));
+ }
+ else
+ {
+ assert(oper == GT_UMOD);
+
+ emit->emitIns_R_I(INS_and, size, targetReg, imm -1);
+ }
+ }
+#else // !0
+ NYI("genCodeForPow2Div");
+#endif // !0
+}
+
+
/***********************************************************************************************
* Generate code for localloc
*/
diff --git a/src/jit/codegenlinear.h b/src/jit/codegenlinear.h
index 6ffccbf593..3c96fbec07 100644
--- a/src/jit/codegenlinear.h
+++ b/src/jit/codegenlinear.h
@@ -20,6 +20,8 @@
void genCodeForMulHi(GenTreeOp* treeNode);
+ void genCodeForPow2Div(GenTreeOp* treeNode);
+
void genLeaInstruction(GenTreeAddrMode *lea);
void genSetRegToCond(regNumber dstReg, GenTreePtr tree);
diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp
index b35268e225..b3354128a6 100644
--- a/src/jit/codegenxarch.cpp
+++ b/src/jit/codegenxarch.cpp
@@ -1284,31 +1284,42 @@ void CodeGen::genCodeForDivMod(GenTreeOp* treeNode)
gcInfo.gcMarkRegSetNpt(RBM_RDX);
}
- // Perform the 'targetType' (64-bit or 32-bit) divide instruction
- instruction ins;
- if (oper == GT_UMOD || oper == GT_UDIV)
- ins = INS_div;
+ if (divisor->isContainedIntOrIImmed())
+ {
+ GenTreeIntConCommon* divImm = divisor->AsIntConCommon();
+ assert(divImm->IsIntCnsFitsInI32());
+ ssize_t imm = divImm->IconValue();
+ assert(isPow2(abs(imm)));
+ genCodeForPow2Div(treeNode->AsOp());
+ }
else
- ins = INS_idiv;
+ {
+ // Perform the 'targetType' (64-bit or 32-bit) divide instruction
+ instruction ins;
+ if (oper == GT_UMOD || oper == GT_UDIV)
+ ins = INS_div;
+ else
+ ins = INS_idiv;
- emit->emitInsBinary(ins, size, treeNode, divisor);
+ emit->emitInsBinary(ins, size, treeNode, divisor);
- // Signed divide RDX:RAX by r/m64, with result
- // stored in RAX := Quotient, RDX := Remainder.
- // Move the result to the desired register, if necessary
- if (oper == GT_DIV || oper == GT_UDIV)
- {
- if (targetReg != REG_RAX)
+ // Signed divide RDX:RAX by r/m64, with result
+ // stored in RAX := Quotient, RDX := Remainder.
+ // Move the result to the desired register, if necessary
+ if (oper == GT_DIV || oper == GT_UDIV)
{
- inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
+ if (targetReg != REG_RAX)
+ {
+ inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
+ }
}
- }
- else
- {
- assert((oper == GT_MOD) || (oper == GT_UMOD));
- if (targetReg != REG_RDX)
+ else
{
- inst_RV_RV(INS_mov, targetReg, REG_RDX, targetType);
+ assert((oper == GT_MOD) || (oper == GT_UMOD));
+ if (targetReg != REG_RDX)
+ {
+ inst_RV_RV(INS_mov, targetReg, REG_RDX, targetType);
+ }
}
}
}
@@ -2879,6 +2890,120 @@ CodeGen::genMultiRegCallStoreToLocal(GenTreePtr treeNode)
#endif // !FEATURE_UNIX_AMD64_STRUCT_PASSING
}
+// Generate code for division (or mod) by power of two
+// or negative powers of two. (meaning -1 * a power of two, not 2^(-1))
+// Op2 must be a contained integer constant.
+void
+CodeGen::genCodeForPow2Div(GenTreeOp* tree)
+{
+ GenTree *dividend = tree->gtOp.gtOp1;
+ GenTree *divisor = tree->gtOp.gtOp2;
+ genTreeOps oper = tree->OperGet();
+ emitAttr size = emitTypeSize(tree);
+ emitter *emit = getEmitter();
+ regNumber targetReg = tree->gtRegNum;
+ var_types targetType = tree->TypeGet();
+
+ bool isSigned = oper == GT_MOD || oper == GT_DIV;
+
+ // precondition: extended dividend is in RDX:RAX
+ // which means it is either all zeros or all ones
+
+ noway_assert(divisor->isContained());
+ GenTreeIntConCommon* divImm = divisor->AsIntConCommon();
+ ssize_t imm = divImm->IconValue();
+ ssize_t abs_imm = abs(imm);
+ noway_assert(isPow2(abs_imm));
+
+
+ if (isSigned)
+ {
+ if (imm == 1)
+ {
+ if (oper == GT_DIV)
+ {
+ if (targetReg != REG_RAX)
+ inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
+ }
+ else
+ {
+ assert(oper == GT_MOD);
+ instGen_Set_Reg_To_Zero(size, targetReg);
+ }
+
+ return;
+ }
+
+ if (abs_imm == 2)
+ {
+ if (oper == GT_MOD)
+ {
+ emit->emitIns_R_I(INS_and, size, REG_RAX, 1); // result is 0 or 1
+ // xor with rdx will flip all bits if negative
+ emit->emitIns_R_R(INS_xor, size, REG_RAX, REG_RDX); // 111.11110 or 0
+ }
+ else
+ {
+ assert(oper == GT_DIV);
+ // add 1 if it's negative
+ emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
+ }
+ }
+ else
+ {
+ // add imm-1 if negative
+ emit->emitIns_R_I(INS_and, size, REG_RDX, abs_imm - 1);
+ emit->emitIns_R_R(INS_add, size, REG_RAX, REG_RDX);
+ }
+
+ if (oper == GT_DIV)
+ {
+ unsigned shiftAmount = genLog2(unsigned(abs_imm));
+ inst_RV_SH(INS_sar, size, REG_RAX, shiftAmount);
+
+ if (imm < 0)
+ {
+ emit->emitIns_R(INS_neg, size, REG_RAX);
+ }
+ }
+ else
+ {
+ assert(oper == GT_MOD);
+ if (abs_imm > 2)
+ {
+ emit->emitIns_R_I(INS_and, size, REG_RAX, abs_imm - 1);
+ }
+ // RDX contains 'imm-1' if negative
+ emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
+ }
+
+ if (targetReg != REG_RAX)
+ {
+ inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
+ }
+ }
+ else
+ {
+ assert (imm > 0);
+
+ if (targetReg != dividend->gtRegNum)
+ {
+ inst_RV_RV(INS_mov, targetReg, dividend->gtRegNum, targetType);
+ }
+
+ if (oper == GT_UDIV)
+ {
+ inst_RV_SH(INS_shr, size, targetReg, genLog2(unsigned(imm)));
+ }
+ else
+ {
+ assert(oper == GT_UMOD);
+
+ emit->emitIns_R_I(INS_and, size, targetReg, imm -1);
+ }
+ }
+}
+
/***********************************************************************************************
* Generate code for localloc
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index 1df4f3bbcd..9e90d9c1fd 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -627,16 +627,6 @@ void Lowering::LowerNode(GenTreePtr* ppTree, Compiler::fgWalkData* data)
LowerAdd(ppTree, data);
break;
- case GT_UDIV:
- case GT_UMOD:
- LowerUnsignedDivOrMod(*ppTree);
- break;
-
- case GT_DIV:
- case GT_MOD:
- LowerSignedDivOrMod(ppTree, data);
- break;
-
case GT_SWITCH:
LowerSwitch(ppTree);
break;
@@ -3470,198 +3460,6 @@ void Lowering::LowerAdd(GenTreePtr* pTree, Compiler::fgWalkData* data)
#endif // !_TARGET_ARMARCH_
}
-//------------------------------------------------------------------------
-// LowerUnsignedDivOrMod: transform GT_UDIV/GT_UMOD nodes with a const power of 2
-// divisor into GT_RSZ/GT_AND nodes.
-//
-// Arguments:
-// tree: pointer to the GT_UDIV/GT_UMOD node to be lowered
-
-void Lowering::LowerUnsignedDivOrMod(GenTree* tree)
-{
- assert(tree->OperGet() == GT_UDIV || tree->OperGet() == GT_UMOD);
-
- GenTree* divisor = tree->gtGetOp2();
-
- if (divisor->IsCnsIntOrI())
- {
- size_t divisorValue = static_cast<size_t>(divisor->gtIntCon.IconValue());
-
- if (isPow2(divisorValue))
- {
- genTreeOps newOper;
-
- if (tree->OperGet() == GT_UDIV)
- {
- newOper = GT_RSZ;
- divisorValue = genLog2(divisorValue);
- }
- else
- {
- newOper = GT_AND;
- divisorValue -= 1;
- }
-
- tree->SetOper(newOper);
- divisor->gtIntCon.SetIconValue(divisorValue);
- }
- }
-}
-
-//------------------------------------------------------------------------
-// LowerSignedDivOrMod: transform integer GT_DIV/GT_MOD nodes with a power of 2
-// const divisor into equivalent but faster sequences.
-//
-// Arguments:
-// pTree: pointer to the parent node's link to the node we care about
-
-void Lowering::LowerSignedDivOrMod(GenTreePtr* ppTree, Compiler::fgWalkData* data)
-{
- GenTree* divMod = *ppTree;
- assert(divMod->OperGet() == GT_DIV || divMod->OperGet() == GT_MOD);
- GenTree* divisor = divMod->gtGetOp2();
-
- if (divisor->IsCnsIntOrI())
- {
- const var_types type = divMod->TypeGet();
- assert(type == TYP_INT || type == TYP_LONG);
-
- GenTree* dividend = divMod->gtGetOp1();
-
- if (dividend->IsCnsIntOrI())
- {
- // We shouldn't see a divmod with constant operands here but if we do then it's likely
- // because optimizations are disabled or it's a case that's supposed to throw an exception.
- // Don't optimize this.
- return;
- }
-
- ssize_t divisorValue = divisor->gtIntCon.IconValue();
-
- if (divisorValue == -1)
- {
- // x / -1 can't be optimized because INT_MIN / -1 is required to throw an exception.
-
- // x % -1 is always 0 and the IL spec says that the rem instruction "can" throw an exception if x is
- // the minimum representable integer. However, the C# spec says that an exception "is" thrown in this
- // case so optimizing this case would break C# code.
-
- // A runtime check could be used to handle this case but it's probably too rare to matter.
- return;
- }
-
- bool isDiv = divMod->OperGet() == GT_DIV;
-
- if (isDiv)
- {
- if ((type == TYP_INT && divisorValue == INT_MIN) ||
- (type == TYP_LONG && divisorValue == INT64_MIN))
- {
- // If the divisor is the minimum representable integer value then we can use a compare,
- // the result is 1 iff the dividend equals divisor.
- divMod->SetOper(GT_EQ);
- return;
- }
- }
-
- size_t absDivisorValue = (divisorValue == SSIZE_T_MIN) ? static_cast<size_t>(divisorValue) : static_cast<size_t>(abs(divisorValue));
-
- if (isPow2(absDivisorValue))
- {
- // We need to use the dividend node multiple times so its value needs to be
- // computed once and stored in a temp variable.
- GenTreeStmt* newStmt = comp->fgInsertEmbeddedFormTemp(&(divMod->gtOp.gtOp1));
- newStmt->gtFlags |= GTF_STMT_SKIP_LOWER;
- dividend = divMod->gtGetOp1();
-
- GenTreeStmt* curStmt = comp->compCurStmt->AsStmt();
- unsigned curBBWeight = currBlock->getBBWeight(comp);
- unsigned dividendLclNum = dividend->gtLclVar.gtLclNum;
-
- GenTree* adjustment = comp->gtNewOperNode(
- GT_RSH, type,
- dividend,
- comp->gtNewIconNode(type == TYP_INT ? 31 : 63));
-
- if (absDivisorValue == 2)
- {
- // If the divisor is +/-2 then we'd end up with a bitwise and between 0/-1 and 1.
- // We can get the same result by using GT_RSZ instead of GT_RSH.
- adjustment->SetOper(GT_RSZ);
- }
- else
- {
- adjustment = comp->gtNewOperNode(
- GT_AND, type,
- adjustment,
- comp->gtNewIconNode(absDivisorValue - 1, type));
- }
-
- GenTree* adjustedDividend = comp->gtNewOperNode(
- GT_ADD, type,
- adjustment,
- comp->gtNewLclvNode(dividendLclNum, type));
-
- comp->lvaTable[dividendLclNum].incRefCnts(curBBWeight, comp);
-
- GenTree* newDivMod;
-
- if (isDiv)
- {
- // perform the division by right shifting the adjusted dividend
- divisor->gtIntCon.SetIconValue(genLog2(absDivisorValue));
-
- newDivMod = comp->gtNewOperNode(
- GT_RSH, type,
- adjustedDividend,
- divisor);
-
- if (divisorValue < 0)
- {
- // negate the result if the divisor is negative
- newDivMod = comp->gtNewOperNode(
- GT_NEG, type,
- newDivMod);
- }
- }
- else
- {
- // divisor % dividend = dividend - divisor x (dividend / divisor)
- // divisor x (dividend / divisor) translates to (dividend >> log2(divisor)) << log2(divisor)
- // which simply discards the low log2(divisor) bits, that's just dividend & ~(divisor - 1)
- divisor->gtIntCon.SetIconValue(~(absDivisorValue - 1));
-
- newDivMod = comp->gtNewOperNode(
- GT_SUB, type,
- comp->gtNewLclvNode(dividendLclNum, type),
- comp->gtNewOperNode(
- GT_AND, type,
- adjustedDividend,
- divisor));
-
- comp->lvaTable[dividendLclNum].incRefCnts(curBBWeight, comp);
- }
-
- // remove the divisor and dividend nodes from linear order so we can reuse them
- comp->fgSnipNode(curStmt, divisor);
- comp->fgSnipNode(curStmt, dividend);
-
- // linearize and insert the new tree before the original divMod node
- comp->gtSetEvalOrder(newDivMod);
- comp->fgSetTreeSeq(newDivMod);
- comp->fgInsertTreeInListBefore(newDivMod, divMod, curStmt);
- comp->fgSnipNode(curStmt, divMod);
-
- // the divMod that we've replaced could have been a call arg
- comp->fgFixupIfCallArg(data->parentStack, divMod, newDivMod);
-
- // replace the original divmod node with the new divmod tree
- *ppTree = newDivMod;
-
- return;
- }
- }
-}
//------------------------------------------------------------------------
// LowerInd: attempt to transform indirected expression into an addressing mode
diff --git a/src/jit/lower.h b/src/jit/lower.h
index 489fac1a6c..6381555949 100644
--- a/src/jit/lower.h
+++ b/src/jit/lower.h
@@ -165,8 +165,6 @@ private:
void LowerInd(GenTreePtr* ppTree);
void LowerAddrMode(GenTreePtr* ppTree, GenTree* before, Compiler::fgWalkData* data, bool isIndir);
void LowerAdd(GenTreePtr* ppTree, Compiler::fgWalkData* data);
- void LowerUnsignedDivOrMod(GenTree* tree);
- void LowerSignedDivOrMod(GenTreePtr* ppTree, Compiler::fgWalkData* data);
// Remove the nodes that are no longer used after an addressing mode is constructed under a GT_IND
void LowerIndCleanupHelper(GenTreeAddrMode* addrMode, GenTreePtr tree);
diff --git a/src/jit/lowerarm64.cpp b/src/jit/lowerarm64.cpp
index c58d4f1379..73724835c4 100644
--- a/src/jit/lowerarm64.cpp
+++ b/src/jit/lowerarm64.cpp
@@ -367,6 +367,7 @@ void Lowering::TreeNodeInfoInit(GenTree* stmt)
case GT_MULHI:
case GT_UDIV:
{
+ // TODO-ARM64-CQ: Optimize a divide by power of 2 as we do for AMD64
info->srcCount = 2;
info->dstCount = 1;
}
diff --git a/src/jit/lowerxarch.cpp b/src/jit/lowerxarch.cpp
index 354dc985bf..cf433ed3f9 100644
--- a/src/jit/lowerxarch.cpp
+++ b/src/jit/lowerxarch.cpp
@@ -575,6 +575,31 @@ void Lowering::TreeNodeInfoInit(GenTree* stmt)
op1 = tree->gtOp.gtOp1;
op2 = tree->gtOp.gtOp2;
+ // See if we have an optimizable power of 2 which will be expanded
+ // using instructions other than division.
+ // (fgMorph has already done magic number transforms)
+
+ if (op2->IsIntCnsFitsInI32())
+ {
+ bool isSigned = tree->OperGet() == GT_MOD || tree->OperGet() == GT_DIV;
+ ssize_t amount = op2->gtIntConCommon.IconValue();
+
+ if (isPow2(abs(amount)) && (isSigned || amount > 0)
+ && amount != -1)
+ {
+ MakeSrcContained(tree, op2);
+
+ if (isSigned)
+ {
+ // we are going to use CDQ instruction so want these RDX:RAX
+ info->setDstCandidates(l, RBM_RAX);
+ // If possible would like to have op1 in RAX to avoid a register move
+ op1->gtLsraInfo.setSrcCandidates(l, RBM_RAX);
+ }
+ break;
+ }
+ }
+
// Amd64 Div/Idiv instruction:
// Dividend in RAX:RDX and computes
// Quotient in RAX, Remainder in RDX
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index 2dbadfc93d..acea3cbfdf 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -12600,7 +12600,7 @@ bool Compiler::fgShouldUseMagicNumberDivide(GenTreeOp* tree)
return false;
// codegen will expand these
- if (cons == SSIZE_T_MIN || isPow2(abs(cons)))
+ if (isPow2(cons))
return false;
// someone else will fold this away, so don't make it complicated for them
diff --git a/tests/src/JIT/CodeGenBringUpTests/DivConst.cs b/tests/src/JIT/CodeGenBringUpTests/DivConst.cs
deleted file mode 100644
index 3a2ca09988..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/DivConst.cs
+++ /dev/null
@@ -1,423 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.CompilerServices;
-
-static class DivConst
-{
- // I4
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Div_0(int i4)
- {
- return i4 / 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Div_1(int i4)
- {
- return i4 / 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Div_Minus1(int i4)
- {
- return i4 / -1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Div_3(int i4)
- {
- return i4 / 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivRef_5(ref int i4)
- {
- return i4 / 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Div_7(int i4)
- {
- return i4 / 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Div_Minus3(int i4)
- {
- return i4 / -3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivPow2_2(int i4)
- {
- return i4 / 2;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivPow2_Minus2(int i4)
- {
- return i4 / -2;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivPow2_8(ref int i4)
- {
- return i4 / 8;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivPow2_Minus4(int i4)
- {
- return i4 / -4;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivPow2_I4Min(int i4)
- {
- return i4 / int.MinValue;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivPow2Embedded_4(int x, int y)
- {
- return y * 2 + (x + 2) / 4 + (x * y >> 31);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_DivPow2Call_8(int i4)
- {
- return I4_DivPow2_2(i4 / 8) + I4_DivRef_5(ref i4) / 8;
- }
-
- // I8
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Div_0(long i8)
- {
- return i8 / 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Div_1(long i8)
- {
- return i8 / 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Div_Minus1(long i8)
- {
- return i8 / -1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Div_3(long i8)
- {
- return i8 / 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Div_5(long i8)
- {
- return i8 / 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Div_7(ref long i8)
- {
- return i8 / 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Div_Minus3(long i8)
- {
- return i8 / -3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_DivPow2_4(long i8)
- {
- return i8 / 4;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_DivPow2_Minus8(long i8)
- {
- return i8 / -8;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_DivUncontainedPow2_1Shl32(long i8)
- {
- return i8 / (1L << 32);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_DivUncontainedPow2_I8Min(long i8)
- {
- return i8 / long.MinValue;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_DivPow2Embedded_4(long x, long y)
- {
- return y * 2 + (x + 2) / 4 + (x * y >> 31);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_DivPow2Call_8(long i8)
- {
- return I8_DivPow2_4(i8 / 8) + I8_Div_5(i8) / 8;
- }
-}
-
-static class DivProgram
-{
- public static int Main()
- {
- const int Pass = 100;
- const int Fail = -1;
-
- // I4
-
- try
- {
- DivConst.I4_Div_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (DivConst.I4_Div_1(42) != 42)
- {
- return Fail;
- }
-
- if (DivConst.I4_Div_Minus1(42) != -42)
- {
- return Fail;
- }
-
- try
- {
- DivConst.I4_Div_Minus1(int.MinValue);
- return Fail;
- }
- catch (OverflowException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (DivConst.I4_Div_3(42) != 14)
- {
- return Fail;
- }
-
- {
- int dividend = 42;
-
- if (DivConst.I4_DivRef_5(ref dividend) != 8)
- {
- return Fail;
- }
- }
-
- if (DivConst.I4_Div_7(42) != 6)
- {
- return Fail;
- }
-
- if (DivConst.I4_Div_Minus3(42) != -14)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_2(42) != 21)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_2(43) != 21)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_2(-42) != -21)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_2(-43) != -21)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_Minus2(43) != -21)
- {
- return Fail;
- }
-
- {
- int dividend = 42;
-
- if (DivConst.I4_DivPow2_8(ref dividend) != 5)
- {
- return Fail;
- }
- }
-
- {
- int dividend = -42;
-
- if (DivConst.I4_DivPow2_8(ref dividend) != -5)
- {
- return Fail;
- }
- }
-
- if (DivConst.I4_DivPow2_Minus4(42) != -10)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_Minus4(-42) != 10)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_I4Min(-42) != 0)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2_I4Min(int.MinValue) != 1)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2Embedded_4(420, 938) != 1981)
- {
- return Fail;
- }
-
- if (DivConst.I4_DivPow2Call_8(420) != 36)
- {
- return Fail;
- }
-
- // I8
-
- try
- {
- DivConst.I8_Div_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Pass;
- }
-
- if (DivConst.I8_Div_1(42) != 42)
- {
- return Fail;
- }
-
- if (DivConst.I8_Div_Minus1(42) != -42)
- {
- return Fail;
- }
-
- try
- {
- DivConst.I8_Div_Minus1(long.MinValue);
- return Fail;
- }
- catch (OverflowException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (DivConst.I8_Div_3(42) != 14)
- {
- return Fail;
- }
-
- if (DivConst.I8_Div_5(42) != 8)
- {
- return Fail;
- }
-
- {
- long dividend = 45;
-
- if (DivConst.I8_Div_7(ref dividend) != 6)
- {
- return Fail;
- }
- }
-
- if (DivConst.I8_Div_Minus3(42) != -14)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivPow2_4(42) != 10)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivPow2_Minus8(42) != -5)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivPow2_Minus8(-42) != 5)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivUncontainedPow2_1Shl32(1L << 33) != 2)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivUncontainedPow2_I8Min(42) != 0)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivUncontainedPow2_I8Min(long.MinValue) != 1)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivPow2Embedded_4(420, 938) != 1981)
- {
- return Fail;
- }
-
- if (DivConst.I8_DivPow2Call_8(420) != 23)
- {
- return Fail;
- }
-
- return Pass;
- }
-}
diff --git a/tests/src/JIT/CodeGenBringUpTests/DivConst.csproj b/tests/src/JIT/CodeGenBringUpTests/DivConst.csproj
deleted file mode 100644
index 58b6823bae..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/DivConst.csproj
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{EC6FD253-5247-4D8C-887E-453B5647A0A7}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- </PropertyGroup>
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <ItemGroup>
- <None Include="$(JitPackagesConfigFileDirectory)threading+thread\project.json" />
- </ItemGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="DivConst.cs" />
- </ItemGroup>
- <PropertyGroup>
- <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
- <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
- </PropertyGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/tests/src/JIT/CodeGenBringUpTests/ModConst.cs b/tests/src/JIT/CodeGenBringUpTests/ModConst.cs
deleted file mode 100644
index 4552fed1b7..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/ModConst.cs
+++ /dev/null
@@ -1,427 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.CompilerServices;
-
-static class ModConst
-{
- // I4
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Mod_0(int i4)
- {
- return i4 % 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Mod_1(int i4)
- {
- return i4 % 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Mod_Minus1(int i4)
- {
- return i4 % -1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Mod_3(int i4)
- {
- return i4 % 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModRef_5(ref int i4)
- {
- return i4 % 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Mod_7(int i4)
- {
- return i4 % 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_Mod_Minus3(int i4)
- {
- return i4 % -3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModPow2_2(int i4)
- {
- return i4 % 2;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModPow2_Minus2(int i4)
- {
- return i4 % -2;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModPow2_8(ref int i4)
- {
- return i4 % 8;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModPow2_Minus4(int i4)
- {
- return i4 % -4;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModPow2_I4Min(ref int i4)
- {
- return i4 % int.MinValue;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModPow2Embedded_4(int x, int y)
- {
- return y * 2 + (x + 2) % 4 + (x * y >> 31);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int I4_ModPow2Call_8(int i4)
- {
- return I4_ModPow2_2(i4 % 8) + I4_ModRef_5(ref i4) % 8;
- }
-
- // I8
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Mod_0(long i8)
- {
- return i8 % 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Mod_1(long i8)
- {
- return i8 % 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Mod_Minus1(long i8)
- {
- return i8 % -1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Mod_3(long i8)
- {
- return i8 % 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Mod_5(long i8)
- {
- return i8 % 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Mod_7(long i8)
- {
- return i8 % 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_Mod_Minus3(long i8)
- {
- return i8 % -3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_ModPow2_4(long i8)
- {
- return i8 % 4;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_ModPow2_Minus8(long i8)
- {
- return i8 % -8;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_ModUncontainedPow2_1Shl32(long i8)
- {
- return i8 % (1L << 32);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_ModUncontainedPow2_I8Min(long i8)
- {
- return i8 % long.MinValue;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_ModPow2Embedded_4(long x, long y)
- {
- return y * 2 + (x + 2) % 4 + (x * y >> 31);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static long I8_ModPow2Call_8(long i8)
- {
- return I8_ModPow2_4(i8 % 8) + I8_Mod_5(i8) % 8;
- }
-}
-
-static class ModProgram
-{
- public static int Main()
- {
- const int Pass = 100;
- const int Fail = -1;
-
- // I4
-
- try
- {
- ModConst.I4_Mod_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (ModConst.I4_Mod_1(42) != 0)
- {
- return Fail;
- }
-
- if (ModConst.I4_Mod_Minus1(42) != 0)
- {
- return Fail;
- }
-
- try
- {
- ModConst.I4_Mod_Minus1(int.MinValue);
- return Fail;
- }
- catch (OverflowException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (ModConst.I4_Mod_3(41) != 2)
- {
- return Fail;
- }
-
- {
- int dividend = 42;
-
- if (ModConst.I4_ModRef_5(ref dividend) != 2)
- {
- return Fail;
- }
- }
-
- if (ModConst.I4_Mod_7(42) != 0)
- {
- return Fail;
- }
-
- if (ModConst.I4_Mod_Minus3(41) != 2)
- {
- return Fail;
- }
-
- if (ModConst.I4_ModPow2_2(43) != 1)
- {
- return Fail;
- }
-
- if (ModConst.I4_ModPow2_2(42) != 0)
- {
- return Fail;
- }
-
- if (ModConst.I4_ModPow2_2(-43) != -1)
- {
- return Fail;
- }
-
- if (ModConst.I4_ModPow2_2(-42) != 0)
- {
- return Fail;
- }
-
- if (ModConst.I4_ModPow2_Minus2(43) != 1)
- {
- return Fail;
- }
-
- {
- int dividend = 42;
-
- if (ModConst.I4_ModPow2_8(ref dividend) != 2)
- {
- return Fail;
- }
- }
-
- {
- int dividend = -42;
-
- if (ModConst.I4_ModPow2_8(ref dividend) != -2)
- {
- return Fail;
- }
- }
-
- if (ModConst.I4_ModPow2_Minus4(42) != 2)
- {
- return Fail;
- }
-
- if (ModConst.I4_ModPow2_Minus4(-42) != -2)
- {
- return Fail;
- }
-
- {
- int dividend = -42;
-
- if (ModConst.I4_ModPow2_I4Min(ref dividend) != -42)
- {
- return Fail;
- }
- }
-
- {
- int dividend = int.MinValue;
-
- if (ModConst.I4_ModPow2_I4Min(ref dividend) != 0)
- {
- return Fail;
- }
- }
-
- if (ModConst.I4_ModPow2Embedded_4(420, 938) != 1878)
- {
- return Fail;
- }
-
- if (ModConst.I4_ModPow2Call_8(3674) != 4)
- {
- return Fail;
- }
-
- // I8
-
- try
- {
- ModConst.I8_Mod_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Pass;
- }
-
- if (ModConst.I8_Mod_1(42) != 0)
- {
- return Fail;
- }
-
- if (ModConst.I8_Mod_Minus1(42) != 0)
- {
- return Fail;
- }
-
- try
- {
- ModConst.I8_Mod_Minus1(long.MinValue);
- return Fail;
- }
- catch (OverflowException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (ModConst.I8_Mod_3(43) != 1)
- {
- return Fail;
- }
-
- if (ModConst.I8_Mod_5(42) != 2)
- {
- return Fail;
- }
-
- if (ModConst.I8_Mod_7(45) != 3)
- {
- return Fail;
- }
-
- if (ModConst.I8_Mod_Minus3(-43) != -1)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModPow2_4(42) != 2)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModPow2_Minus8(42) != 2)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModPow2_Minus8(-42) != -2)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModUncontainedPow2_1Shl32((1L << 33) + 42L) != 42)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModUncontainedPow2_I8Min(42) != 42)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModUncontainedPow2_I8Min(long.MinValue) != 0)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModPow2Embedded_4(420, 938) != 1878)
- {
- return Fail;
- }
-
- if (ModConst.I8_ModPow2Call_8(3674) != 6)
- {
- return Fail;
- }
-
- return Pass;
- }
-}
diff --git a/tests/src/JIT/CodeGenBringUpTests/ModConst.csproj b/tests/src/JIT/CodeGenBringUpTests/ModConst.csproj
deleted file mode 100644
index 7e04c9223b..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/ModConst.csproj
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{314823E3-7BB2-4C19-BA04-5AC565215BA3}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- </PropertyGroup>
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <ItemGroup>
- <None Include="$(JitPackagesConfigFileDirectory)threading+thread\project.json" />
- </ItemGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="ModConst.cs" />
- </ItemGroup>
- <PropertyGroup>
- <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
- <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
- </PropertyGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/tests/src/JIT/CodeGenBringUpTests/UDivConst.cs b/tests/src/JIT/CodeGenBringUpTests/UDivConst.cs
deleted file mode 100644
index cd507fe554..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/UDivConst.cs
+++ /dev/null
@@ -1,219 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.CompilerServices;
-
-static class UDivConst
-{
- // U4
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Div_0(uint u4)
- {
- return u4 / 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Div_1(uint u4)
- {
- return u4 / 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Div_3(uint u4)
- {
- return u4 / 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Div_5(uint u4)
- {
- return u4 / 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Div_7(uint u4)
- {
- return u4 / 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_DivPow2_16(uint u4)
- {
- return u4 / 16;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_DivPow2_I4Min(uint u4)
- {
- return u4 / 0x80000000u;
- }
-
- // U8
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Div_0(ulong u8)
- {
- return u8 / 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Div_1(ulong u8)
- {
- return u8 / 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Div_3(ulong u8)
- {
- return u8 / 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Div_5(ulong u8)
- {
- return u8 / 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Div_7(ulong u8)
- {
- return u8 / 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_DivUncontained_I8Max(ulong u8)
- {
- return u8 / ulong.MaxValue;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_DivPow2_2(ulong u8)
- {
- return u8 / 2;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_DivUncontainedPow2_1Shl32(ulong u8)
- {
- return u8 / (1UL << 32);
- }
-}
-
-static class UDivProgram
-{
- public static int Main()
- {
- const int Pass = 100;
- const int Fail = -1;
-
- // U4
-
- try
- {
- UDivConst.U4_Div_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (UDivConst.U4_Div_1(42) != 42)
- {
- return Fail;
- }
-
- if (UDivConst.U4_Div_3(42) != 14)
- {
- return Fail;
- }
-
- if (UDivConst.U4_Div_5(42) != 8)
- {
- return Fail;
- }
-
- if (UDivConst.U4_Div_7(43) != 6)
- {
- return Fail;
- }
-
- if (UDivConst.U4_DivPow2_16(42) != 2)
- {
- return Fail;
- }
-
- if (UDivConst.U4_DivPow2_I4Min(3) != 0)
- {
- return Fail;
- }
-
- if (UDivConst.U4_DivPow2_I4Min(0x80000001u) != 1)
- {
- return Fail;
- }
-
- // U8
-
- try
- {
- UDivConst.U8_Div_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (UDivConst.U8_Div_1(42) != 42)
- {
- return Fail;
- }
-
- if (UDivConst.U8_Div_3(42) != 14)
- {
- return Fail;
- }
-
- if (UDivConst.U8_Div_5(42) != 8)
- {
- return Fail;
- }
-
- if (UDivConst.U8_Div_7(420) != 60)
- {
- return Fail;
- }
-
- if (UDivConst.U8_DivUncontained_I8Max(ulong.MaxValue - 1) != 0)
- {
- return Fail;
- }
-
- if (UDivConst.U8_DivUncontained_I8Max(ulong.MaxValue) != 1)
- {
- return Fail;
- }
-
- if (UDivConst.U8_DivPow2_2(42) != 21)
- {
- return Fail;
- }
-
- if (UDivConst.U8_DivUncontainedPow2_1Shl32(1UL << 33) != 2)
- {
- return Fail;
- }
-
- return Pass;
- }
-}
diff --git a/tests/src/JIT/CodeGenBringUpTests/UDivConst.csproj b/tests/src/JIT/CodeGenBringUpTests/UDivConst.csproj
deleted file mode 100644
index 81a799ad87..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/UDivConst.csproj
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{53C70B64-C175-43BF-A98A-719868D6D695}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- </PropertyGroup>
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <ItemGroup>
- <None Include="$(JitPackagesConfigFileDirectory)threading+thread\project.json" />
- </ItemGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="UDivConst.cs" />
- </ItemGroup>
- <PropertyGroup>
- <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
- <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
- </PropertyGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/tests/src/JIT/CodeGenBringUpTests/UModConst.cs b/tests/src/JIT/CodeGenBringUpTests/UModConst.cs
deleted file mode 100644
index 06cc28d8a8..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/UModConst.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.CompilerServices;
-
-static class UModConst
-{
- // U4
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Mod_0(uint u4)
- {
- return u4 % 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Mod_1(uint u4)
- {
- return u4 % 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Mod_3(uint u4)
- {
- return u4 % 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Mod_5(uint u4)
- {
- return u4 % 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_Mod_7(uint u4)
- {
- return u4 % 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_ModPow2_16(uint u4)
- {
- return u4 % 16;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static uint U4_ModPow2_0x80000000(uint u4)
- {
- return u4 % 0x80000000u;
- }
-
- // U8
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Mod_0(ulong u8)
- {
- return u8 % 0;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Mod_1(ulong u8)
- {
- return u8 % 1;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Mod_3(ulong u8)
- {
- return u8 % 3;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Mod_5(ulong u8)
- {
- return u8 % 5;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_Mod_7(ulong u8)
- {
- return u8 % 7;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_ModUncontained_I8Max(ulong u8)
- {
- return u8 % ulong.MaxValue;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_ModPow2_8(ulong u8)
- {
- return u8 % 8;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static ulong U8_ModUncontainedPow2_1Shl32(ulong u8)
- {
- return u8 % (1UL << 32);
- }
-}
-
-static class UModProgram
-{
- public static int Main()
- {
- const int Pass = 100;
- const int Fail = -1;
-
- // U4
-
- try
- {
- UModConst.U4_Mod_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (UModConst.U4_Mod_1(42) != 0)
- {
- return Fail;
- }
-
- if (UModConst.U4_Mod_3(43) != 1)
- {
- return Fail;
- }
-
- if (UModConst.U4_Mod_5(42) != 2)
- {
- return Fail;
- }
-
- if (UModConst.U4_Mod_7(43) != 1)
- {
- return Fail;
- }
-
- if (UModConst.U4_ModPow2_16(42) != 10)
- {
- return Fail;
- }
-
- if (UModConst.U4_ModPow2_0x80000000(3) != 3)
- {
- return Fail;
- }
-
- if (UModConst.U4_ModPow2_0x80000000(0x80000001u) != 1)
- {
- return Fail;
- }
-
- // U8
-
- try
- {
- UModConst.U8_Mod_0(42);
- return Fail;
- }
- catch (DivideByZeroException)
- {
- }
- catch (Exception)
- {
- return Fail;
- }
-
- if (UModConst.U8_Mod_1(42) != 0)
- {
- return Fail;
- }
-
- if (UModConst.U8_Mod_3(43) != 1)
- {
- return Fail;
- }
-
- if (UModConst.U8_Mod_5(42) != 2)
- {
- return Fail;
- }
-
- if (UModConst.U8_Mod_7(420) != 0)
- {
- return Fail;
- }
-
- if (UModConst.U8_ModUncontained_I8Max(ulong.MaxValue - 1) != ulong.MaxValue - 1)
- {
- return Fail;
- }
-
- if (UModConst.U8_ModUncontained_I8Max(ulong.MaxValue) != 0)
- {
- return Fail;
- }
-
- if (UModConst.U8_ModPow2_8(42) != 2)
- {
- return Fail;
- }
-
- if (UModConst.U8_ModPow2_8(43) != 3)
- {
- return Fail;
- }
-
- if (UModConst.U8_ModUncontainedPow2_1Shl32((1UL << 33) + 42) != 42)
- {
- return Fail;
- }
-
- return Pass;
- }
-}
diff --git a/tests/src/JIT/CodeGenBringUpTests/UModConst.csproj b/tests/src/JIT/CodeGenBringUpTests/UModConst.csproj
deleted file mode 100644
index 942ffbe8cb..0000000000
--- a/tests/src/JIT/CodeGenBringUpTests/UModConst.csproj
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{D7512FD8-08E1-4BB6-8701-E3FEEAE4FF66}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- </PropertyGroup>
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <ItemGroup>
- <None Include="$(JitPackagesConfigFileDirectory)threading+thread\project.json" />
- </ItemGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="UModConst.cs" />
- </ItemGroup>
- <PropertyGroup>
- <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
- <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
- </PropertyGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file