diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp index 27d29dfb47e4..537aa06835fd 100644 --- a/src/jit/lsra.cpp +++ b/src/jit/lsra.cpp @@ -8728,6 +8728,10 @@ void LinearScan::dumpNodeInfo(GenTree* node, regMaskTP dstCandidates, int srcCou void LinearScan::dumpDefList() { + if (!VERBOSE) + { + return; + } JITDUMP("DefList: { "); bool first = true; for (RefInfoListNode *listNode = defList.Begin(), *end = defList.End(); listNode != end; diff --git a/src/jit/lsraarmarch.cpp b/src/jit/lsraarmarch.cpp index 1804d4caff88..dad8a7519751 100644 --- a/src/jit/lsraarmarch.cpp +++ b/src/jit/lsraarmarch.cpp @@ -512,16 +512,18 @@ int LinearScan::BuildPutArgSplit(GenTreePutArgSplit* argNode) assert(!node->IsMultiRegNode()); currentRegCount = 1; } - regMaskTP sourceMask = RBM_NONE; - if (sourceRegCount < argNode->gtNumRegs) + // Consume all the registers, setting the appropriate register mask for the ones that + // go into registers. + for (unsigned regIndex = 0; regIndex < currentRegCount; regIndex++) { - for (unsigned regIndex = 0; regIndex < currentRegCount; regIndex++) + regMaskTP sourceMask = RBM_NONE; + if (sourceRegCount < argNode->gtNumRegs) { - sourceMask |= genRegMask((regNumber)((unsigned)argReg + sourceRegCount + regIndex)); + sourceMask = genRegMask((regNumber)((unsigned)argReg + sourceRegCount)); } + sourceRegCount++; + BuildUse(node, sourceMask, regIndex); } - sourceRegCount += currentRegCount; - BuildUse(node, sourceMask); } srcCount += sourceRegCount; assert(putArgChild->isContained()); diff --git a/src/jit/lsrabuild.cpp b/src/jit/lsrabuild.cpp index 14a8ab7c6d73..0d0efa9efa5f 100644 --- a/src/jit/lsrabuild.cpp +++ b/src/jit/lsrabuild.cpp @@ -2091,7 +2091,11 @@ void LinearScan::buildIntervals() // Note: the visited set is cleared in LinearScan::doLinearScan() markBlockVisited(block); - assert(defList.IsEmpty()); + if (!defList.IsEmpty()) + { + INDEBUG(dumpDefList()); + assert(!"Expected empty defList at end of block"); + } if (enregisterLocalVars) { diff --git a/tests/arm/Tests.lst b/tests/arm/Tests.lst index db556779e9dc..eac6ca40ddff 100644 --- a/tests/arm/Tests.lst +++ b/tests/arm/Tests.lst @@ -94804,3 +94804,11 @@ MaxAllowedDurationSeconds=600 Categories=EXPECTED_PASS HostStyle=0 +[GitHub_18362.cmd_11911] +RelativePath=JIT\Regression\JitBlue\GitHub_18362\GitHub_18362\GitHub_18362.cmd +WorkingDir=JIT\Regression\JitBlue\GitHub_18362\GitHub_18362 +Expected=0 +MaxAllowedDurationSeconds=600 +Categories=EXPECTED_PASS +HostStyle=0 + diff --git a/tests/arm64/Tests.lst b/tests/arm64/Tests.lst index 4d7592873474..9d97229af493 100644 --- a/tests/arm64/Tests.lst +++ b/tests/arm64/Tests.lst @@ -94827,3 +94827,11 @@ Expected=0 MaxAllowedDurationSeconds=600 Categories=EXPECTED_PASS HostStyle=0 +[GitHub_18362.cmd_12231] +RelativePath=JIT\Regression\JitBlue\GitHub_18362\GitHub_18362\GitHub_18362.cmd +WorkingDir=JIT\Regression\JitBlue\GitHub_18362\GitHub_18362 +Expected=0 +MaxAllowedDurationSeconds=600 +Categories=EXPECTED_PASS +HostStyle=0 + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_18362/GitHub_18362.cs b/tests/src/JIT/Regression/JitBlue/GitHub_18362/GitHub_18362.cs new file mode 100644 index 000000000000..695ca20981a5 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_18362/GitHub_18362.cs @@ -0,0 +1,112 @@ +// 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.Numerics; +using System.Runtime.CompilerServices; + +// This is a struct that will be passed as a split struct +struct S +{ + public double d1; + public double d2; +}; + +static class GitHub_18362 +{ + private static bool AreSameInfinity(double d1, double d2) + { + return + double.IsNegativeInfinity(d1) == double.IsNegativeInfinity(d2) && + double.IsPositiveInfinity(d1) == double.IsPositiveInfinity(d2); + } + + private static bool IsDiffTolerable(double d1, double d2) + { + if (double.IsInfinity(d1)) + { + return AreSameInfinity(d1, d2 * 10); + } + if (double.IsInfinity(d2)) + { + return AreSameInfinity(d1 * 10, d2); + } + double diffRatio = (d1 - d2) / d1; + diffRatio *= Math.Pow(10, 6); + return Math.Abs(diffRatio) < 1; + } + + private static void VerifyRealImaginaryProperties(Complex complex, double real, double imaginary, [CallerLineNumber] int lineNumber = 0) + { + if (!real.Equals(complex.Real) && !IsDiffTolerable(complex.Real, real)) + { + Console.WriteLine("Failure at line {0}. Expected real: {1}. Actual real: {2}", lineNumber, real, complex.Real); + throw new Exception(); + } + if (!imaginary.Equals(complex.Imaginary) && !IsDiffTolerable(complex.Imaginary, imaginary)) + { + Console.WriteLine("Failure at line {0}. Expected imaginary: {1}. Actual imaginary: {2}", lineNumber, imaginary, complex.Imaginary); + throw new Exception(); + } + } + + + private static void VerifyMagnitudePhaseProperties(Complex complex, double magnitude, double phase, [CallerLineNumber] int lineNumber = 0) + { + // The magnitude (m) of a complex number (z = x + yi) is the absolute value - |z| = sqrt(x^2 + y^2) + // Verification is done using the square of the magnitude since m^2 = x^2 + y^2 + double expectedMagnitudeSquared = magnitude * magnitude; + double actualMagnitudeSquared = complex.Magnitude * complex.Magnitude; + + if (!expectedMagnitudeSquared.Equals(actualMagnitudeSquared) && !IsDiffTolerable(actualMagnitudeSquared, expectedMagnitudeSquared)) + { + Console.WriteLine("Failure at line {0}. Expected magnitude squared: {1}. Actual magnitude squared: {2}", lineNumber, expectedMagnitudeSquared, actualMagnitudeSquared); + throw new Exception(); + } + + if (double.IsNaN(magnitude)) + { + phase = double.NaN; + } + else if (magnitude == 0) + { + phase = 0; + } + else if (magnitude < 0) + { + phase += (phase < 0) ? Math.PI : -Math.PI; + } + + if (!phase.Equals(complex.Phase) && !IsDiffTolerable(complex.Phase, phase)) + { + Console.WriteLine("Failure at line {0}. Expected phase: {1}. Actual phase: {2}", lineNumber, phase, complex.Phase); + throw new Exception(); + } + } + + public static void Conjugate(double real, double imaginary) + { + int returnVal = 100; + + var complex = new Complex(real, imaginary); + Complex result = Complex.Conjugate(complex); + + VerifyRealImaginaryProperties(result, real, -imaginary); + VerifyMagnitudePhaseProperties(result, complex.Magnitude, -complex.Phase); + } + + [MethodImpl(MethodImplOptions.NoOptimization)] + static int Main() + { + try + { + Conjugate(2.0, 3.0); + } + catch (Exception e) + { + return -1; + } + return 100; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_18362/GitHub_18362.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_18362/GitHub_18362.csproj new file mode 100644 index 000000000000..ea8e8a7e429f --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_18362/GitHub_18362.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + False + + + + + True + True + + + + + + + + + + + + + +