From bfc1444e6b42b9c20559f8000e5d4d19d71eeeac Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 11 Sep 2024 14:47:20 -0700 Subject: [PATCH 01/12] make sure the upperHalf is moved to ready pool when lowerHalf holding DOUBLE interval is done --- src/coreclr/jit/lsra.cpp | 68 ++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 3f603fa0c221b..16edccab03230 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9714,6 +9714,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, } } + // kpathak + bool startLogging = false; + bool revertChange = false; + if ((fromBlock->bbNum == 12) && (toBlock->bbNum == 13)) + { + printf("targetRegsToDo=%x\n", targetRegsToDo); + startLogging = true; + } // First: // - Perform all moves from reg to stack (no ordering needed on these) // - For reg to reg moves, record the current location, associating their @@ -9776,9 +9784,16 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, source[toReg] = (regNumberSmall)fromReg; sourceIntervals[fromReg] = interval; targetRegsToDo |= genRegMask(toReg); + if (startLogging && genIsValidFloatReg(fromReg)) + { + printf("Added "); + interval->tinyDump(); + printf(" for %s -> %s (%s). targetRegsToDo= ", getRegName(fromReg), getRegName(toReg), ((interval->registerType == TYP_DOUBLE)? "double" : "float")); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } } } - // REGISTER to REGISTER MOVES // First, find all the ones that are ready to move now @@ -9800,12 +9815,17 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, Interval* interval = sourceIntervals[sourceReg]; Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (startLogging && genIsValidFloatReg(sourceReg)) + { + printf("For "); + interval->tinyDump(); + printf(" from %s -> %s.\n", getRegName(sourceReg), getRegName(targetReg)); + } + if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; } - if (interval->registerType == TYP_DOUBLE) { // Condition 1 above. @@ -9839,10 +9859,27 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // Perform reg to reg moves while (targetRegsToDo.IsNonEmpty()) { + if (startLogging) + { + printf("targetRegsReady: "); + compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); + printf(", targetRegsToDo: "); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } while (targetRegsReady.IsNonEmpty()) { regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady); targetRegsToDo.RemoveRegNumFromMask(targetReg); + if (startLogging) + { + printf("targetReg: %s, ", getRegName(targetReg)); + printf("targetRegsReady: "); + compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); + printf(", targetRegsToDo: "); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } assert(location[targetReg] != targetReg); assert(targetReg < REG_COUNT); regNumber sourceReg = (regNumber)source[targetReg]; @@ -9854,6 +9891,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, assert(interval != nullptr); addResolution(block, insertionPoint, interval, targetReg, fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); + if (startLogging && genIsValidFloatReg(sourceReg)) + { + printf("Added resolution: %s -> %s\n", getRegName(fromReg), getRegName(targetReg)); + printf(" Removing "); + interval->tinyDump(); + printf("for %s.\n", getRegName(sourceReg)); + } sourceIntervals[sourceReg] = nullptr; location[sourceReg] = REG_NA; @@ -9875,6 +9919,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, { targetRegsReady.RemoveRegNumFromMask(fromReg); } + if ((source[upperHalfReg] != REG_NA) && !targetRegsFromStack.IsRegNumInMask(upperHalfReg)) + { + // Also, if the other half, which is not resolved from the stack, is a target of + // an unrelated interval, free it up after the above resolution of TYP_DOUBLE took place. + Interval* upperHalfInterval = sourceIntervals[source[upperHalfReg]]; + assert((upperHalfInterval != nullptr) && (upperHalfInterval->registerType == TYP_FLOAT)); + targetRegsReady.AddRegNumInMask(upperHalfReg); + } } } else if (genIsValidFloatReg(fromReg) && !genIsValidDoubleReg(fromReg)) @@ -9889,10 +9941,8 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // - There is a source register for this reg (lowerHalfSrcReg != REG_NA) // - It is currently free (lowerHalfSrcLoc == REG_NA) // - The source interval isn't yet completed (sourceIntervals[lowerHalfSrcReg] != nullptr) - // - It's not in the ready set ((targetRegsReady & lowerHalfRegMask) == - // RBM_NONE) - // - It's not resolved from stack ((targetRegsFromStack & lowerHalfRegMask) != - // lowerHalfRegMask) + // - It's not in the ready set (!targetRegsReady.IsRegNumInMask(lowerHalfReg)) + // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(lowerHalfReg)) if ((lowerHalfSrcReg != REG_NA) && (lowerHalfSrcLoc == REG_NA) && (sourceIntervals[lowerHalfSrcReg] != nullptr) && !targetRegsReady.IsRegNumInMask(lowerHalfReg) && @@ -10048,7 +10098,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, #ifdef TARGET_ARM Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; @@ -10073,7 +10123,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, { assert(sourceIntervals[targetReg] != nullptr); - addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg, + addResolution(block, insertionPoint, sourceIntervals[fromReg], tempReg, targetReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); location[targetReg] = (regNumberSmall)tempReg; From d8f2f173df2c01fde0abea207bf329c48253e228 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 11 Sep 2024 15:01:51 -0700 Subject: [PATCH 02/12] remove the logging --- src/coreclr/jit/lsra.cpp | 52 ++++------------------------------------ 1 file changed, 4 insertions(+), 48 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 16edccab03230..5e726b2b68300 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9714,14 +9714,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, } } - // kpathak - bool startLogging = false; - bool revertChange = false; - if ((fromBlock->bbNum == 12) && (toBlock->bbNum == 13)) - { - printf("targetRegsToDo=%x\n", targetRegsToDo); - startLogging = true; - } // First: // - Perform all moves from reg to stack (no ordering needed on these) // - For reg to reg moves, record the current location, associating their @@ -9784,14 +9776,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, source[toReg] = (regNumberSmall)fromReg; sourceIntervals[fromReg] = interval; targetRegsToDo |= genRegMask(toReg); - if (startLogging && genIsValidFloatReg(fromReg)) - { - printf("Added "); - interval->tinyDump(); - printf(" for %s -> %s (%s). targetRegsToDo= ", getRegName(fromReg), getRegName(toReg), ((interval->registerType == TYP_DOUBLE)? "double" : "float")); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } } } // REGISTER to REGISTER MOVES @@ -9815,13 +9799,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, Interval* interval = sourceIntervals[sourceReg]; Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (startLogging && genIsValidFloatReg(sourceReg)) - { - printf("For "); - interval->tinyDump(); - printf(" from %s -> %s.\n", getRegName(sourceReg), getRegName(targetReg)); - } - if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; @@ -9859,27 +9837,11 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // Perform reg to reg moves while (targetRegsToDo.IsNonEmpty()) { - if (startLogging) - { - printf("targetRegsReady: "); - compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); - printf(", targetRegsToDo: "); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } while (targetRegsReady.IsNonEmpty()) { regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady); targetRegsToDo.RemoveRegNumFromMask(targetReg); - if (startLogging) - { - printf("targetReg: %s, ", getRegName(targetReg)); - printf("targetRegsReady: "); - compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); - printf(", targetRegsToDo: "); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } + assert(location[targetReg] != targetReg); assert(targetReg < REG_COUNT); regNumber sourceReg = (regNumber)source[targetReg]; @@ -9891,13 +9853,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, assert(interval != nullptr); addResolution(block, insertionPoint, interval, targetReg, fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); - if (startLogging && genIsValidFloatReg(sourceReg)) - { - printf("Added resolution: %s -> %s\n", getRegName(fromReg), getRegName(targetReg)); - printf(" Removing "); - interval->tinyDump(); - printf("for %s.\n", getRegName(sourceReg)); - } + sourceIntervals[sourceReg] = nullptr; location[sourceReg] = REG_NA; @@ -10098,7 +10054,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, #ifdef TARGET_ARM Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; From db4cc7bf3874b9684151c6b6813d256f19595c10 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 11 Sep 2024 15:04:08 -0700 Subject: [PATCH 03/12] added test cases --- .../JitBlue/Runtime_107621/Runtime_107621.cs | 314 ++++++++++++++++++ .../Runtime_107621/Runtime_107621.csproj | 8 + 2 files changed, 322 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.csproj diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs b/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs new file mode 100644 index 0000000000000..5a533ffd840c5 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs @@ -0,0 +1,314 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Generated by Fuzzlyn v2.4 on 2024-09-10 14:15:16 +// Run on Arm Linux +// Seed: 9455791714420973255 +// Reduced from 119.7 KiB to 12.1 KiB in 00:15:49 +// Hits JIT assert in Release: +// Assertion failed 'sourceIntervals[targetReg] != nullptr' in 'Program:M8(byref,S0):long' during 'LSRA allocate' (IL size 7341; hash 0x093e6d2a; FullOpts) +// +// File: /__w/1/s/src/coreclr/jit/lsra.cpp Line: 10074 +// +using System; +namespace _107621 +{ + public struct S0 + { + public bool F0; + public long F1; + public long F2; + public float F3; + public byte F5; + public sbyte F6; + public S0(long f2, float f3, double f4, sbyte f6) : this() + { + } + } + + public class C0 + { + public long F0; + public S0 F2; + public S0 F3; + public long F5; + public C0(double f1, S0 f2, S0 f3, double f4, long f5) + { + } + } + + public struct S1 + { + public bool F1; + public S0 F2; + public C0 F3; + public byte F4; + public uint F5; + public S1(S0 f2, C0 f3) : this() + { + } + + public short M10() + { + return default(short); + } + } + + public class Program + { + public static IRuntime s_rt; + public static ulong s_1; + public static C0 s_5 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0); + public static ushort[] s_7; + public static C0 s_11 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0); + + [Fact] + public static void TestEntryPoint() + { + try + { + var vr12 = s_11.F2; + M8(ref s_5.F3.F3, vr12); + } catch {} + } + + private static long M8(ref float arg0, S0 arg1) + { + double var1 = default(double); + bool var8 = default(bool); + if (arg1.F0) + { + if (M9()) + { + sbyte[,,] var0 = new sbyte[,,] + { + { + { + 1 + } + } + }; + arg0 = (arg1.F1 * new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)).M10()); + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, -1), 0, 0)).M10(); + new S1(new S0(0, 0, 0, 0), new C0(-1.7976931348623157E+308d, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)).M10(); + s_rt.WriteLine(var0[0, 0, 0]); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var1)); + byte var3 = arg1.F5++; + var vr7 = new S1[] + { + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(-1922739055833068276L, 0, 0, 1), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(-9223372036854775808L, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(9223372036854775807L, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(-9223372036854775808L, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(3366051754928502355L, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)) + }; + ref float vr16 = ref vr7[0].F3.F3.F3; + vr16 = (s_1 >> s_7[0]--); + var vr8 = new S1[] + { + new S1(new S0(-7780288970767849613L, 0, 0, 127), new C0(0, new S0(-7247354589903316995L, 0, 0, 1), new S0(3332629451991572720L, 0, 0, 0), 0, 0)), + new S1(new S0(9223372036854775806L, 0, 0, 0), new C0(0, new S0(56844987229889904L, 0, 0, 0), new S0(9223372036854775806L, 3.4028235E+38f, 0, -49), 0, -2954444398035812513L)), + new S1(new S0(9223372036854775807L, 0, 0, -127), new C0(0, new S0(9223372036854775807L, 0, 0, -127), new S0(-8108349655554254125L, 0, 0, -128), 0, 0)) + }; + float vr19 = vr8[0].F3.F3.F3; + C0 var4 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0); + s_rt.WriteLine(var3); + s_rt.WriteLine(var4.F0); + s_rt.WriteLine(var4.F2.F0); + s_rt.WriteLine(var4.F2.F5); + s_rt.WriteLine(var4.F3.F0); + s_rt.WriteLine(var4.F3.F1); + s_rt.WriteLine(var4.F3.F2); + s_rt.WriteLine(var4.F3.F5); + s_rt.WriteLine(var4.F5); + } + + for (int var5 = 0; var5 < 2; var5++) + { + var vr5 = new S1[] + { + new S1(new S0(0, 1, 1, 0), new C0(0, new S0(0, 1, -1, 0), new S0(0, 1, -2261.3113161007714d, 1), 0, 0)), + new S1(new S0(0, 1, 0, 0), new C0(0, new S0(0, 3.4028235E+38f, -1.7976931348623157E+308d, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)) + }; + } + + S1 var6 = new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, -1), 0, 0)); + s_rt.WriteLine(var6.F1); + s_rt.WriteLine(var6.F2.F0); + s_rt.WriteLine(var6.F2.F2); + s_rt.WriteLine(var6.F2.F5); + s_rt.WriteLine(var6.F2.F6); + s_rt.WriteLine(var6.F3.F0); + s_rt.WriteLine(var6.F3.F2.F0); + s_rt.WriteLine(var6.F3.F2.F2); + s_rt.WriteLine(var6.F3.F2.F5); + s_rt.WriteLine(var6.F3.F2.F6); + s_rt.WriteLine(var6.F3.F3.F0); + s_rt.WriteLine(var6.F3.F3.F5); + s_rt.WriteLine(var6.F3.F3.F6); + s_rt.WriteLine(var6.F3.F5); + s_rt.WriteLine(var6.F4); + s_rt.WriteLine(var6.F5); + } + else + { + var vr6 = new S1[] + { + new S1(new S0(0, -1, -1.7976931348623157E+308d, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, -1, 0, 0), 1, 0)), + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 3.4028235E+38f, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)) + }; + float vr22 = vr6[0].F3.F3.F3; + arg1.F5 = (byte)vr22; + C0 var7 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0); + var7.F3.F3--; + s_7 = new ushort[] + { + 1 + }; + sbyte[] var9 = new sbyte[] + { + 1 + }; + if (s_5.F2.F0) + { + uint[] var10 = new uint[] + { + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0 + }; + var vr1 = new S1[] + { + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, -1), 0, 0)) + }; + sbyte var11 = (sbyte)(var10[0] - M11(vr1)); + s_rt.WriteLine(var10[0]); + s_rt.WriteLine(var11); + } + else + { + ulong[] var12 = new ulong[] + { + 1 + }; + s_rt.WriteLine(var12[0]); + } + + if (s_5.F2.F0) + { + var vr3 = new S1[] + { + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, -1, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, -1), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)) + }; + C0[] var13 = new C0[] + { + new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0), + new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0) + }; + s_rt.WriteLine(var13[0].F0); + s_rt.WriteLine(var13[0].F2.F1); + s_rt.WriteLine(var13[0].F2.F2); + s_rt.WriteLine(var13[0].F2.F5); + s_rt.WriteLine(var13[0].F2.F6); + s_rt.WriteLine(var13[0].F3.F0); + s_rt.WriteLine(var13[0].F3.F1); + s_rt.WriteLine(var13[0].F3.F2); + s_rt.WriteLine(var13[0].F3.F5); + s_rt.WriteLine(var13[0].F3.F6); + s_rt.WriteLine(var13[0].F5); + } + else + { + return arg1.F2++; + } + + var7.F3.F3 = var7.F2.F3--; + float var14 = arg1.F3; + s_rt.WriteLine(System.BitConverter.SingleToUInt32Bits(var14)); + s_rt.WriteLine(var8); + var vr9 = new S1[] + { + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)) + }; + var vr10 = new S1[] + { + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 1, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)) + }; + s_rt.WriteLine(var7.F0); + s_rt.WriteLine(var7.F2.F0); + s_rt.WriteLine(var7.F2.F1); + s_rt.WriteLine(var7.F2.F2); + s_rt.WriteLine(var7.F2.F5); + s_rt.WriteLine(var7.F2.F6); + s_rt.WriteLine(var7.F3.F0); + s_rt.WriteLine(var7.F3.F1); + s_rt.WriteLine(var7.F3.F5); + s_rt.WriteLine(var7.F3.F6); + s_rt.WriteLine(var7.F5); + } + + for (int var15 = 0; var15 < 1; var15++) + { + var vr2 = new S1[] + { + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, -1.7976931348623157E+308d, 0), new S0(0, 0, 0, 0), 0, 0)), + new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 3.4028235E+38f, 0, 0), new S0(0, 0, 0, 0), 0, 0)) + }; + } + + return 0; + } + + private static bool M9() + { + return default(bool); + } + + private static ref float M11(S1[] arg0) + { + return ref arg0[0].F3.F3.F3; + } + } + + public interface IRuntime + { + void WriteLine(T value); + } + + public class Runtime : IRuntime + { + public void WriteLine(T value) => System.Console.WriteLine(value); + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.csproj new file mode 100644 index 0000000000000..de6d5e08882e8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 70c62ee7d03bd8d49df1b9aff4b5d659835a481b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 11 Sep 2024 15:15:06 -0700 Subject: [PATCH 04/12] fix a typo --- src/coreclr/jit/lsra.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 5e726b2b68300..9a0111299f61f 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9778,6 +9778,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, targetRegsToDo |= genRegMask(toReg); } } + // REGISTER to REGISTER MOVES // First, find all the ones that are ready to move now @@ -10079,7 +10080,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, { assert(sourceIntervals[targetReg] != nullptr); - addResolution(block, insertionPoint, sourceIntervals[fromReg], tempReg, + addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg, targetReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); location[targetReg] = (regNumberSmall)tempReg; From fb593e0366e84f89cc34de7fdf1f0e694d269542 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 11 Sep 2024 16:35:41 -0700 Subject: [PATCH 05/12] Add missing Xunit reference --- .../JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs b/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs index 5a533ffd840c5..028015c05ec75 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_107621/Runtime_107621.cs @@ -11,6 +11,8 @@ // File: /__w/1/s/src/coreclr/jit/lsra.cpp Line: 10074 // using System; +using Xunit; + namespace _107621 { public struct S0 From fb9d02f03f5cda39f3bb6285ac76c558835682c8 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 12 Sep 2024 07:28:27 -0700 Subject: [PATCH 06/12] Revert "remove the logging" This reverts commit d8f2f173df2c01fde0abea207bf329c48253e228. --- src/coreclr/jit/lsra.cpp | 52 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 9a0111299f61f..97a5e7e536a0b 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9714,6 +9714,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, } } + // kpathak + bool startLogging = false; + bool revertChange = false; + if ((fromBlock->bbNum == 12) && (toBlock->bbNum == 13)) + { + printf("targetRegsToDo=%x\n", targetRegsToDo); + startLogging = true; + } // First: // - Perform all moves from reg to stack (no ordering needed on these) // - For reg to reg moves, record the current location, associating their @@ -9776,6 +9784,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, source[toReg] = (regNumberSmall)fromReg; sourceIntervals[fromReg] = interval; targetRegsToDo |= genRegMask(toReg); + if (startLogging && genIsValidFloatReg(fromReg)) + { + printf("Added "); + interval->tinyDump(); + printf(" for %s -> %s (%s). targetRegsToDo= ", getRegName(fromReg), getRegName(toReg), ((interval->registerType == TYP_DOUBLE)? "double" : "float")); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } } } @@ -9800,7 +9816,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, Interval* interval = sourceIntervals[sourceReg]; Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (startLogging && genIsValidFloatReg(sourceReg)) + { + printf("For "); + interval->tinyDump(); + printf(" from %s -> %s.\n", getRegName(sourceReg), getRegName(targetReg)); + } + if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; @@ -9838,11 +9860,27 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // Perform reg to reg moves while (targetRegsToDo.IsNonEmpty()) { + if (startLogging) + { + printf("targetRegsReady: "); + compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); + printf(", targetRegsToDo: "); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } while (targetRegsReady.IsNonEmpty()) { regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady); targetRegsToDo.RemoveRegNumFromMask(targetReg); - + if (startLogging) + { + printf("targetReg: %s, ", getRegName(targetReg)); + printf("targetRegsReady: "); + compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); + printf(", targetRegsToDo: "); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } assert(location[targetReg] != targetReg); assert(targetReg < REG_COUNT); regNumber sourceReg = (regNumber)source[targetReg]; @@ -9854,7 +9892,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, assert(interval != nullptr); addResolution(block, insertionPoint, interval, targetReg, fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); - + if (startLogging && genIsValidFloatReg(sourceReg)) + { + printf("Added resolution: %s -> %s\n", getRegName(fromReg), getRegName(targetReg)); + printf(" Removing "); + interval->tinyDump(); + printf("for %s.\n", getRegName(sourceReg)); + } sourceIntervals[sourceReg] = nullptr; location[sourceReg] = REG_NA; @@ -10055,7 +10099,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, #ifdef TARGET_ARM Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; From 7869b0596518691a60614a768b4dbf6b68f0812b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 12 Sep 2024 14:30:39 -0700 Subject: [PATCH 07/12] better fix to free up upperHalf if lowerHalf is getting freed up --- src/coreclr/jit/lsra.cpp | 78 +++++++++++----------------------------- 1 file changed, 20 insertions(+), 58 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 97a5e7e536a0b..fbff4f711f06f 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9714,14 +9714,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, } } - // kpathak - bool startLogging = false; - bool revertChange = false; - if ((fromBlock->bbNum == 12) && (toBlock->bbNum == 13)) - { - printf("targetRegsToDo=%x\n", targetRegsToDo); - startLogging = true; - } // First: // - Perform all moves from reg to stack (no ordering needed on these) // - For reg to reg moves, record the current location, associating their @@ -9784,14 +9776,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, source[toReg] = (regNumberSmall)fromReg; sourceIntervals[fromReg] = interval; targetRegsToDo |= genRegMask(toReg); - if (startLogging && genIsValidFloatReg(fromReg)) - { - printf("Added "); - interval->tinyDump(); - printf(" for %s -> %s (%s). targetRegsToDo= ", getRegName(fromReg), getRegName(toReg), ((interval->registerType == TYP_DOUBLE)? "double" : "float")); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } } } @@ -9816,13 +9800,8 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, Interval* interval = sourceIntervals[sourceReg]; Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (startLogging && genIsValidFloatReg(sourceReg)) - { - printf("For "); - interval->tinyDump(); - printf(" from %s -> %s.\n", getRegName(sourceReg), getRegName(targetReg)); - } - if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + + if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; @@ -9860,27 +9839,11 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // Perform reg to reg moves while (targetRegsToDo.IsNonEmpty()) { - if (startLogging) - { - printf("targetRegsReady: "); - compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); - printf(", targetRegsToDo: "); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } while (targetRegsReady.IsNonEmpty()) { regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady); targetRegsToDo.RemoveRegNumFromMask(targetReg); - if (startLogging) - { - printf("targetReg: %s, ", getRegName(targetReg)); - printf("targetRegsReady: "); - compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); - printf(", targetRegsToDo: "); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } + assert(location[targetReg] != targetReg); assert(targetReg < REG_COUNT); regNumber sourceReg = (regNumber)source[targetReg]; @@ -9892,13 +9855,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, assert(interval != nullptr); addResolution(block, insertionPoint, interval, targetReg, fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); - if (startLogging && genIsValidFloatReg(sourceReg)) - { - printf("Added resolution: %s -> %s\n", getRegName(fromReg), getRegName(targetReg)); - printf(" Removing "); - interval->tinyDump(); - printf("for %s.\n", getRegName(sourceReg)); - } + sourceIntervals[sourceReg] = nullptr; location[sourceReg] = REG_NA; @@ -9916,17 +9873,22 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // - the other half of the double is free. Interval* otherInterval = sourceIntervals[source[fromReg]]; regNumber upperHalfReg = REG_NEXT(fromReg); - if ((otherInterval->registerType == TYP_DOUBLE) && (location[upperHalfReg] != REG_NA)) - { - targetRegsReady.RemoveRegNumFromMask(fromReg); - } - if ((source[upperHalfReg] != REG_NA) && !targetRegsFromStack.IsRegNumInMask(upperHalfReg)) + + if (otherInterval->registerType == TYP_DOUBLE) { - // Also, if the other half, which is not resolved from the stack, is a target of - // an unrelated interval, free it up after the above resolution of TYP_DOUBLE took place. - Interval* upperHalfInterval = sourceIntervals[source[upperHalfReg]]; - assert((upperHalfInterval != nullptr) && (upperHalfInterval->registerType == TYP_FLOAT)); - targetRegsReady.AddRegNumInMask(upperHalfReg); + // If the interval targeting fromReg is double... + if (location[upperHalfReg] != REG_NA) + { + // .. and the other half is a busy target, then fromReg is not yet ready either. + targetRegsReady.RemoveRegNumFromMask(fromReg); + } + else if (!targetRegsFromStack.IsRegNumInMask(upperHalfReg) && targetRegsToDo.IsRegNumInMask(upperHalfReg)) + { + // ... if the other half (that is not resolved from the stack), is a target of + // an unrelated interval, and got freed up after the above resolution of TYP_DOUBLE took place, + // make it ready as well. + targetRegsReady.AddRegNumInMask(upperHalfReg); + } } } } @@ -10099,7 +10061,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, #ifdef TARGET_ARM Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; From f97b11dacc4d20be31307fee2ecd9e25fdb04768 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 12 Sep 2024 14:35:38 -0700 Subject: [PATCH 08/12] jit format --- src/coreclr/jit/lsra.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index fbff4f711f06f..bb2499dd718f1 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9876,17 +9876,18 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, if (otherInterval->registerType == TYP_DOUBLE) { - // If the interval targeting fromReg is double... + // If the interval targeting fromReg is TYP_DOUBLE... if (location[upperHalfReg] != REG_NA) { // .. and the other half is a busy target, then fromReg is not yet ready either. targetRegsReady.RemoveRegNumFromMask(fromReg); } - else if (!targetRegsFromStack.IsRegNumInMask(upperHalfReg) && targetRegsToDo.IsRegNumInMask(upperHalfReg)) + else if (!targetRegsFromStack.IsRegNumInMask(upperHalfReg) && + targetRegsToDo.IsRegNumInMask(upperHalfReg)) { // ... if the other half (that is not resolved from the stack), is a target of - // an unrelated interval, and got freed up after the above resolution of TYP_DOUBLE took place, - // make it ready as well. + // an unrelated interval, and got freed up after the above resolution of TYP_DOUBLE took + // place, make it ready as well. targetRegsReady.AddRegNumInMask(upperHalfReg); } } From 90eb68cc1360cf2f432ef6e20564cbfa95409ea1 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 12 Sep 2024 21:12:20 -0700 Subject: [PATCH 09/12] Revert "remove the logging" This reverts commit d8f2f173df2c01fde0abea207bf329c48253e228. --- src/coreclr/jit/lsra.cpp | 53 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index bb2499dd718f1..7e85be9021530 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9714,6 +9714,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, } } + // kpathak + bool startLogging = false; + bool revertChange = false; + if ((fromBlock->bbNum == 12) && (toBlock->bbNum == 13)) + { + printf("targetRegsToDo=%x\n", targetRegsToDo); + startLogging = true; + } // First: // - Perform all moves from reg to stack (no ordering needed on these) // - For reg to reg moves, record the current location, associating their @@ -9776,6 +9784,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, source[toReg] = (regNumberSmall)fromReg; sourceIntervals[fromReg] = interval; targetRegsToDo |= genRegMask(toReg); + if (startLogging && genIsValidFloatReg(fromReg)) + { + printf("Added "); + interval->tinyDump(); + printf(" for %s -> %s (%s). targetRegsToDo= ", getRegName(fromReg), getRegName(toReg), ((interval->registerType == TYP_DOUBLE)? "double" : "float")); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } } } @@ -9800,8 +9816,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, Interval* interval = sourceIntervals[sourceReg]; Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - - if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (startLogging && genIsValidFloatReg(sourceReg)) + { + printf("For "); + interval->tinyDump(); + printf(" from %s -> %s.\n", getRegName(sourceReg), getRegName(targetReg)); + } + if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; @@ -9839,11 +9860,27 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // Perform reg to reg moves while (targetRegsToDo.IsNonEmpty()) { + if (startLogging) + { + printf("targetRegsReady: "); + compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); + printf(", targetRegsToDo: "); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } while (targetRegsReady.IsNonEmpty()) { regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady); targetRegsToDo.RemoveRegNumFromMask(targetReg); - + if (startLogging) + { + printf("targetReg: %s, ", getRegName(targetReg)); + printf("targetRegsReady: "); + compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); + printf(", targetRegsToDo: "); + compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); + printf("\n"); + } assert(location[targetReg] != targetReg); assert(targetReg < REG_COUNT); regNumber sourceReg = (regNumber)source[targetReg]; @@ -9855,7 +9892,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, assert(interval != nullptr); addResolution(block, insertionPoint, interval, targetReg, fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); - + if (startLogging && genIsValidFloatReg(sourceReg)) + { + printf("Added resolution: %s -> %s\n", getRegName(fromReg), getRegName(targetReg)); + printf(" Removing "); + interval->tinyDump(); + printf("for %s.\n", getRegName(sourceReg)); + } sourceIntervals[sourceReg] = nullptr; location[sourceReg] = REG_NA; @@ -10062,7 +10105,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, #ifdef TARGET_ARM Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; From c3d8550833e4f84baed72d8aeb36ad0fe247f4f7 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 12 Sep 2024 22:12:09 -0700 Subject: [PATCH 10/12] Handle upperHalf fix similar to lowerHalf code --- src/coreclr/jit/lsra.cpp | 88 +++++++++++----------------------------- 1 file changed, 24 insertions(+), 64 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 7e85be9021530..8556201e8ff4f 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9714,14 +9714,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, } } - // kpathak - bool startLogging = false; - bool revertChange = false; - if ((fromBlock->bbNum == 12) && (toBlock->bbNum == 13)) - { - printf("targetRegsToDo=%x\n", targetRegsToDo); - startLogging = true; - } // First: // - Perform all moves from reg to stack (no ordering needed on these) // - For reg to reg moves, record the current location, associating their @@ -9784,14 +9776,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, source[toReg] = (regNumberSmall)fromReg; sourceIntervals[fromReg] = interval; targetRegsToDo |= genRegMask(toReg); - if (startLogging && genIsValidFloatReg(fromReg)) - { - printf("Added "); - interval->tinyDump(); - printf(" for %s -> %s (%s). targetRegsToDo= ", getRegName(fromReg), getRegName(toReg), ((interval->registerType == TYP_DOUBLE)? "double" : "float")); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } } } @@ -9816,13 +9800,8 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, Interval* interval = sourceIntervals[sourceReg]; Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (startLogging && genIsValidFloatReg(sourceReg)) - { - printf("For "); - interval->tinyDump(); - printf(" from %s -> %s.\n", getRegName(sourceReg), getRegName(targetReg)); - } - if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + + if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; @@ -9860,27 +9839,11 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // Perform reg to reg moves while (targetRegsToDo.IsNonEmpty()) { - if (startLogging) - { - printf("targetRegsReady: "); - compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); - printf(", targetRegsToDo: "); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } while (targetRegsReady.IsNonEmpty()) { regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady); targetRegsToDo.RemoveRegNumFromMask(targetReg); - if (startLogging) - { - printf("targetReg: %s, ", getRegName(targetReg)); - printf("targetRegsReady: "); - compiler->dumpRegMask(targetRegsReady.getLow(), TYP_FLOAT); - printf(", targetRegsToDo: "); - compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT); - printf("\n"); - } + assert(location[targetReg] != targetReg); assert(targetReg < REG_COUNT); regNumber sourceReg = (regNumber)source[targetReg]; @@ -9892,13 +9855,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, assert(interval != nullptr); addResolution(block, insertionPoint, interval, targetReg, fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType])); - if (startLogging && genIsValidFloatReg(sourceReg)) - { - printf("Added resolution: %s -> %s\n", getRegName(fromReg), getRegName(targetReg)); - printf(" Removing "); - interval->tinyDump(); - printf("for %s.\n", getRegName(sourceReg)); - } sourceIntervals[sourceReg] = nullptr; location[sourceReg] = REG_NA; @@ -9916,21 +9872,26 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // - the other half of the double is free. Interval* otherInterval = sourceIntervals[source[fromReg]]; regNumber upperHalfReg = REG_NEXT(fromReg); + if ((otherInterval->registerType == TYP_DOUBLE) && (location[upperHalfReg] != REG_NA)) + { + targetRegsReady.RemoveRegNumFromMask(fromReg); + } - if (otherInterval->registerType == TYP_DOUBLE) + // Since we want to check if we can free upperHalfReg, only do it + // if lowerHalfReg is ready. + if (targetRegsReady.IsRegNumInMask(fromReg)) { - // If the interval targeting fromReg is TYP_DOUBLE... - if (location[upperHalfReg] != REG_NA) - { - // .. and the other half is a busy target, then fromReg is not yet ready either. - targetRegsReady.RemoveRegNumFromMask(fromReg); - } - else if (!targetRegsFromStack.IsRegNumInMask(upperHalfReg) && - targetRegsToDo.IsRegNumInMask(upperHalfReg)) + regNumber upperHalfSrcReg = (regNumber)source[upperHalfReg]; + regNumber upperHalfSrcLoc = (regNumber)location[upperHalfReg]; + // Necessary conditions: + // - There is a source register for this reg (upperHalfSrcReg != REG_NA) + // - It is currently free (upperHalfSrcLoc == REG_NA) + // - The source interval isn't yet completed (sourceIntervals[upperHalfSrcReg] != nullptr) + // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg)) + if ((upperHalfSrcReg != REG_NA) && (upperHalfSrcLoc == REG_NA) && + (sourceIntervals[upperHalfSrcReg] != nullptr) && + !targetRegsFromStack.IsRegNumInMask(upperHalfReg)) { - // ... if the other half (that is not resolved from the stack), is a target of - // an unrelated interval, and got freed up after the above resolution of TYP_DOUBLE took - // place, make it ready as well. targetRegsReady.AddRegNumInMask(upperHalfReg); } } @@ -9940,10 +9901,9 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, { // We may have freed up the other half of a double where the lower half // was already free. - regNumber lowerHalfReg = REG_PREV(fromReg); - regNumber lowerHalfSrcReg = (regNumber)source[lowerHalfReg]; - regNumber lowerHalfSrcLoc = (regNumber)location[lowerHalfReg]; - regMaskTP lowerHalfRegMask = genRegMask(lowerHalfReg); + regNumber lowerHalfReg = REG_PREV(fromReg); + regNumber lowerHalfSrcReg = (regNumber)source[lowerHalfReg]; + regNumber lowerHalfSrcLoc = (regNumber)location[lowerHalfReg]; // Necessary conditions: // - There is a source register for this reg (lowerHalfSrcReg != REG_NA) // - It is currently free (lowerHalfSrcLoc == REG_NA) @@ -10105,7 +10065,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, #ifdef TARGET_ARM Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (!revertChange && genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; From e7955ecf9385e232a3f9538b53a0fa86fd108e9c Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 12 Sep 2024 22:13:39 -0700 Subject: [PATCH 11/12] formatting --- src/coreclr/jit/lsra.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 8556201e8ff4f..80cda203a7a0f 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9800,12 +9800,12 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, Interval* interval = sourceIntervals[sourceReg]; Interval* otherTargetInterval = nullptr; regNumber otherHalfTargetReg = REG_NA; - if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) { otherHalfTargetReg = REG_PREV(targetReg); otherTargetInterval = sourceIntervals[otherHalfTargetReg]; } + if (interval->registerType == TYP_DOUBLE) { // Condition 1 above. @@ -9843,7 +9843,6 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, { regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady); targetRegsToDo.RemoveRegNumFromMask(targetReg); - assert(location[targetReg] != targetReg); assert(targetReg < REG_COUNT); regNumber sourceReg = (regNumber)source[targetReg]; @@ -9887,7 +9886,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // - There is a source register for this reg (upperHalfSrcReg != REG_NA) // - It is currently free (upperHalfSrcLoc == REG_NA) // - The source interval isn't yet completed (sourceIntervals[upperHalfSrcReg] != nullptr) - // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg)) + // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg)) if ((upperHalfSrcReg != REG_NA) && (upperHalfSrcLoc == REG_NA) && (sourceIntervals[upperHalfSrcReg] != nullptr) && !targetRegsFromStack.IsRegNumInMask(upperHalfReg)) From 4f89106e528aa87f3fa6228f625f78ccf536c5db Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 13 Sep 2024 09:42:43 -0700 Subject: [PATCH 12/12] jit format --- src/coreclr/jit/lsra.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 80cda203a7a0f..dd766c51e3da7 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9886,7 +9886,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, // - There is a source register for this reg (upperHalfSrcReg != REG_NA) // - It is currently free (upperHalfSrcLoc == REG_NA) // - The source interval isn't yet completed (sourceIntervals[upperHalfSrcReg] != nullptr) - // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg)) + // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg)) if ((upperHalfSrcReg != REG_NA) && (upperHalfSrcLoc == REG_NA) && (sourceIntervals[upperHalfSrcReg] != nullptr) && !targetRegsFromStack.IsRegNumInMask(upperHalfReg))