diff options
author | Steve MacLean <sdmaclea.qdt@qualcommdatacenter.com> | 2017-09-12 11:15:26 -0400 |
---|---|---|
committer | Steve MacLean <sdmaclea.qdt@qualcommdatacenter.com> | 2017-09-12 11:16:51 -0400 |
commit | ee977d8f782780bdad1b24531f818957e3f3b5e5 (patch) | |
tree | 991923589fd543205d668f9b16b011ed380d4ee9 /src | |
parent | d396160e75cfd01ba5d4a8b2f6610917b62a1106 (diff) | |
download | coreclr-ee977d8f782780bdad1b24531f818957e3f3b5e5.tar.gz coreclr-ee977d8f782780bdad1b24531f818957e3f3b5e5.tar.bz2 coreclr-ee977d8f782780bdad1b24531f818957e3f3b5e5.zip |
Add comments per review
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/morph.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index bdb5307de9..dc2471fc67 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -11869,30 +11869,40 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac) } #ifdef _TARGET_ARM64_ - // For ARM64 we don't have a remainder instruction, // The architecture manual suggests the following transformation to // generate code for such operator: // // a % b = a - (a / b) * b; // - // Use the suggested transform unless the special case transform works: + // We will use the suggested transform except in the special case + // when the modulo operation is unsigned and the divisor is a + // integer constant power of two. In this case, we will rely on lower + // to make the transform: // // a % b = a & (b - 1); // + // Note: We must always perform one or the other of these transforms. + // Therefore we must also detect the special cases where lower does not do the + // % to & transform. In our case there is only currently one extra condition: + // + // * Dividend must not be constant. Lower disables this rare const % const case + // { - bool doMorph = !op2->IsIntegralConst() || op1->IsCnsIntOrI() || (tree->OperGet() == GT_MOD); - - if (!doMorph) + // Do "a % b = a - (a / b) * b" morph if ................... + bool doMorphModToSubMulDiv = !op2->IsIntegralConst() || // Divisor is not an integer constant + (tree->OperGet() == GT_MOD) || // Modulo operation is signed + op1->IsCnsIntOrI(); // Dividend is constant + if (!doMorphModToSubMulDiv) // Dividend is not a power of two { size_t divisorValue = (tree->OperGet() == GT_MOD) && (tree->TypeGet() == TYP_INT) ? op2->AsIntCon()->IconValue() & UINT32_MAX : op2->AsIntCon()->IconValue(); - doMorph |= !isPow2(divisorValue); + doMorphModToSubMulDiv |= !isPow2(divisorValue); } - if (doMorph) + if (doMorphModToSubMulDiv) { assert(!optValnumCSE_phase); @@ -11901,7 +11911,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac) op2 = tree->gtOp.gtOp2; } } -#else //_TARGET_ARM64_ +#else // !_TARGET_ARM64_ // If b is not a power of 2 constant then lowering replaces a % b // with a - (a / b) * b and applies magic division optimization to // a / b. The code may already contain an a / b expression (e.g. |