From ac4b7c683823034908a86a392cd5883362ca20dc Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Mon, 9 Sep 2024 15:52:00 -0700 Subject: [PATCH] Arm: Consider the fact that targetReg can be second half during resolution (#107493) * Arm: Consider the fact that targetReg can be second half during resolution * add test case * Make sure we only handle float registers * fix test case's public methods --- src/coreclr/jit/lsra.cpp | 57 +++- .../JitBlue/Runtime_105619/Runtime_105619.cs | 246 ++++++++++++++++++ .../Runtime_105619/Runtime_105619.csproj | 8 + 3 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.csproj diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 763a28989b3a8..3f603fa0c221b 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -9789,10 +9789,26 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, if (location[targetReg] == REG_NA) { #ifdef TARGET_ARM - regNumber sourceReg = (regNumber)source[targetReg]; - Interval* interval = sourceIntervals[sourceReg]; + // For Arm, check two things: + // 1. If sourceReg relates to DOUBLE interval, then make sure + // the second half of targetReg is not participating in the resolution. + // 2. On the contrary, if targetReg is second half of a DOUBLE interval, + // then make sure the first half is not participating in the resolution. + // Only when both these conditions are met, can we safely assume + // that sourceReg can be moved to targetReg. + regNumber sourceReg = (regNumber)source[targetReg]; + 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. // For ARM32, make sure that both of the float halves of the double register are available. assert(genIsValidDoubleReg(targetReg)); regNumber anotherHalfRegNum = REG_NEXT(targetReg); @@ -9801,11 +9817,22 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, targetRegsReady.AddRegNumInMask(targetReg); } } + else if ((otherTargetInterval != nullptr) && (otherTargetInterval->registerType == TYP_DOUBLE)) + { + // Condition 2 above. + assert(otherHalfTargetReg != REG_NA); + if (location[otherHalfTargetReg] == REG_NA) + { + targetRegsReady.AddRegNumInMask(targetReg); + } + } else -#endif // TARGET_ARM { targetRegsReady.AddRegNumInMask(targetReg); } +#else + targetRegsReady.AddRegNumInMask(targetReg); +#endif } } @@ -10019,6 +10046,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, { compiler->codeGen->regSet.rsSetRegsModified(genRegMask(tempReg) DEBUGARG(true)); #ifdef TARGET_ARM + Interval* otherTargetInterval = nullptr; + regNumber otherHalfTargetReg = REG_NA; + if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg)) + { + otherHalfTargetReg = REG_PREV(targetReg); + otherTargetInterval = sourceIntervals[otherHalfTargetReg]; + } if (sourceIntervals[fromReg]->registerType == TYP_DOUBLE) { assert(genIsValidDoubleReg(targetReg)); @@ -10027,8 +10061,15 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, addResolutionForDouble(block, insertionPoint, sourceIntervals, location, tempReg, targetReg, resolveType DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock)); } + else if (otherTargetInterval != nullptr) + { + assert(otherHalfTargetReg != REG_NA); + assert(otherTargetInterval->registerType == TYP_DOUBLE); + + addResolutionForDouble(block, insertionPoint, sourceIntervals, location, tempReg, + otherHalfTargetReg, resolveType DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock)); + } else -#endif // TARGET_ARM { assert(sourceIntervals[targetReg] != nullptr); @@ -10037,6 +10078,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, DEBUG_ARG(resolveTypeName[resolveType])); location[targetReg] = (regNumberSmall)tempReg; } +#else + assert(sourceIntervals[targetReg] != nullptr); + + addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg, + targetReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) + DEBUG_ARG(resolveTypeName[resolveType])); + location[targetReg] = (regNumberSmall)tempReg; +#endif // TARGET_ARM targetRegsReady |= targetRegMask; } } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.cs b/src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.cs new file mode 100644 index 0000000000000..1956903c95f15 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.cs @@ -0,0 +1,246 @@ +// 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.1 on 2024-07-28 15:37:46 +// Run on Arm Linux +// Seed: 8024459297219020330 +// Reduced from 3285.8 KiB to 12.2 KiB in 01:46:03 +// Hits JIT assert in Release: +// Assertion failed 'varDsc->IsAlwaysAliveInMemory() || ((regSet.GetMaskVars() & regMask) == 0)' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Generate code' (IL size 7170; hash 0xade6b36b; FullOpts) +// +// File: /__w/1/s/src/coreclr/jit/codegencommon.cpp Line: 664 +// +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public interface I1 +{ +} + +public struct S0 +{ + public double F0; + public sbyte F1; + public ulong F2; + public int F3; + public ulong F4; + public ulong F6; + public int F7; + public long F8; + public S0(double f0, ulong f2, ulong f4, float f5, ulong f6, int f7, long f8) : this() + { + } +} + +public struct S1 +{ + public int F0; + public S0 F2; + public S0 F3; + public S0 F4; + public S1(int f0, double f1, S0 f2, S0 f3, S0 f4) : this() + { + } +} + +public struct S2 : I1 +{ + public S1 F2; + public ushort F4; + public S1 F6; + public S1 F7; + public S2(sbyte f0, ulong f1, S1 f2, ushort f4, byte f5, S1 f6, S1 f7) : this() + { + } +} + +public class C0 +{ + public S1 F1; + public C0(S1 f1) + { + } +} + +public struct S3 : I1 +{ + public S3(short f0) : this() + { + } +} + +public struct S4 : I1 +{ + public S3 F0; + public S2 F1; + public S4(S3 f0, S2 f1, float f2, S0 f3, int f5) : this() + { + } +} + +public struct S5 +{ + public C0 F0; + public S5(C0 f0, S1 f3) : this() + { + } +} + +public class C1 +{ + public bool F1; +} + +public class Program +{ + public static IRuntime s_rt; + public static S2 s_13; + public static S1 s_18; + public static bool[] s_22; + public static C0 s_24; + public static ushort[, ] s_31; + public static S1 s_35; + public static bool s_37; + public static S5[] s_44; + public static S4 s_54; + public static S1 s_58; + public static C1[, ] s_59; + public static S4 s_60; + public static S2 s_88; + public static S2[] s_90; + + [Fact] + public static void TestEntryPoint() + { + try + { + CollectibleALC alc = new CollectibleALC(); + System.Reflection.Assembly asm = alc.LoadFromAssemblyPath(System.Reflection.Assembly.GetExecutingAssembly().Location); + System.Reflection.MethodInfo mi = asm.GetType(typeof(Program).FullName).GetMethod(nameof(MainInner)); + System.Type runtimeTy = asm.GetType(typeof(Runtime).FullName); + mi.Invoke(null, new object[] { System.Activator.CreateInstance(runtimeTy) }); + } catch {} + } + +// Allow reflection lookup on public method +#pragma warning disable xUnit1013 + public static void MainInner(IRuntime rt) + { + S0 vr8 = default(S0); + if (s_59[0, 0].F1) + { + bool[] vr9 = new bool[] + { + true + }; + s_88 = new S2(s_54.F1.F2.F4.F1, s_24.F1.F2.F4--, new S1(s_35.F2.F3, 0, new S0(-2, 0, 0, 0, 11218621709493063492UL, 450420498, 0), s_60.F1.F7.F2, new S0(0, 0, 0, 0, 0, 1, 0)), s_13.F4--, (byte)s_31[0, 0], new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), s_54.F1.F2); + vr9[0] = vr9[0]; + } + + s_rt.WriteLine("c_6973", vr8.F2); + s_rt.WriteLine("c_6975", vr8.F4); + s_rt.WriteLine("c_6978", vr8.F7); + I1[] vr10 = new I1[] + { + new S2(0, 0, new S1(0, 0, new S0(0, 0, 0, -3.4028235E+38F, 0, 0, 0), new S0(0, 0, 0, 1, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 0, 0, new S1(1, 0, new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(0, 0, new S0(0, 0, 16728947367172946933UL, 0, 0, 0, 0), new S0(1, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))), + new S3(0), + new S2(0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 1, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 2102657202, 0)), new S1(0, 0, new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 16794536930986757818UL, 0, 0, 0, 0, 0), new S0(0, 0, 11911619636908597430UL, 0, 0, 0, 0))), + new S3(0), + new S2(0, 0, new S1(-2147483647, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 1, 0, new S1(0, -2, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(1, 0, 0, 0, 0, 0, 0)), new S1(1, 1, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0))), + new S2(0, 0, new S1(0, -1, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 0, 0, new S1(-1, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, -3.4028235E+38F, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0)), new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))), + new S4(new S3(0), new S2(1, 0, new S1(0, 1, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0)), 1, 0, new S1(1, 0, new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0)), new S1(0, 0, new S0(0, 0, 0, 0, 0, 1, 0), new S0(1, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))), 0, new S0(0, 0, 0, 0, 0, 0, 0), 0) + }; + var vr11 = new S3(0); + var vr12 = s_44[0].F0.F1.F3.F0; + M75(vr11, vr12); + if (s_22[0]) + { + S3 vr13 = new S3(0); + try + { + var vr14 = s_54.F0; + var vr15 = s_18.F4.F0; + S3 vr23 = vr14; + } + finally + { + var vr16 = new S3(0); + var vr17 = s_58.F4.F0--; + M75(vr16, vr17); + if (s_37) + { + for (int vr18 = 0; vr18 < 2; vr18++) + { + var vr19 = new S3(0); + vr10[0] = new S4(new S3(0), new S2(1, 5461410436353764379UL, new S1(0, 0, new S0(0, 18446744073709551614UL, 0, 0, 17533718527758593297UL, 0, 0), new S0(0, 8592301711847430801UL, 0, 0, 0, 0, 0), new S0(-1, 7862269010569978854UL, 0, 0, 0, 0, 0)), 0, 0, new S1(0, 0, new S0(0, 3156588052453432602UL, 0, 0, 0, 810788132, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(1, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 15070356010362475091UL, 0, 0))), 0, new S0(0, 0, 0, 0, 0, 0, 0), 0); + vr10 = new I1[] + { + new S2(1, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, -3.4028235E+38F, 0, -1, 0), new S0(0, 7703692348755595801UL, 0, 0, 0, 0, 0)), 0, 0, new S1(1, 1.7976931348623157E+308, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0)), new S1(0, -1, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 3991586019811875011UL, 0, 0, 0, -2147483648, 0))), + new S4(new S3(-1), new S2(0, 9890997199408041578UL, new S1(0, 0, new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 0, 0, 0, 0, 0, -7424873608279851173L), new S0(0, 0, 9698347484967702837UL, 0, 0, 0, 0)), 0, 0, new S1(0, 0, new S0(1, 0, 0, 0, 0, 0, 8154649548600176800L), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, -9223372036854775808L)), new S1(0, 0, new S0(1, 0, 0, 0, 0, 0, 0), new S0(0, 778004003835070330UL, 0, 0, 0, 0, 0), new S0(0, 0, 8658698987098108904UL, 0, 0, 0, 0))), 0, new S0(0, 0, 0, 0, 0, 0, 0), 956596481), + new S4(new S3(0), new S2(0, 453734974695362841UL, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, -8941433507005588199L)), 0, 1, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0)), new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 10794758865549560580UL, 0, 7077610171127139841UL, 1, 0), new S0(1, 0, 0, 0, 0, 0, 0))), 0, new S0(1, 0, 0, 0, 17621340021635995622UL, 0, 0), 1), + new S2(0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(1, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(0, 0, new S0(1, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))), + new S2(0, 6130557987521252430UL, new S1(0, -2, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0), new S0(1, 12555188232274105334UL, 0, 0, 0, 0, 0)), 1, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(0, 0, new S0(0, 1828388993980413842UL, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 5800380996067047058UL, 0, 0))), + new S3(1) + }; + s_rt.WriteLine("c_7152", vr18); + } + + S0 vr20 = new S0(0, 0, 0, 0, 0, 0, 0); + C0 vr21 = new C0(new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))); + s_rt.WriteLine("c_7159", vr20.F6); + s_rt.WriteLine("c_7164", vr21.F1.F0); + s_rt.WriteLine("c_7168", vr21.F1.F2.F2); + s_rt.WriteLine("c_7170", vr21.F1.F2.F4); + s_rt.WriteLine("c_7173", vr21.F1.F2.F7); + s_rt.WriteLine("c_7176", vr21.F1.F3.F1); + s_rt.WriteLine("c_7177", vr21.F1.F3.F2); + s_rt.WriteLine("c_7181", vr21.F1.F3.F6); + s_rt.WriteLine("c_7185", vr21.F1.F4.F1); + s_rt.WriteLine("c_7191", vr21.F1.F4.F7); + s_rt.WriteLine("c_7192", vr21.F1.F4.F8); + } + + s_54.F1.F2.F0 = s_90[0].F6.F0++; + } + + var vr22 = new S5(new C0(new S1(0, 0, new S0(-2, 0, 0, 0, 0, 0, 0), new S0(1, 0, 0, 0, 0, -1, 0), new S0(0, 0, 0, 0, 0, 0, 0))), new S1(0, 0, new S0(-1, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))); + } + + vr10 = new I1[] + { + new S4(new S3(-18643), new S2(0, 0, new S1(1, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 11398096482162480173UL, 0, 0, 0, 9223372036854775806L), new S0(0, 0, 0, 0, 0, 2134113955, 0)), 0, 0, new S1(0, 0, new S0(0, 0, 15971873843035984033UL, 0, 5979847448536525346UL, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(1, 0, 0, 0, 11276959574309188693UL, 0, 0)), new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 0, 0, 0, 0, 0, 0))), 0, new S0(0, 0, 0, 0, 0, 0, 0), 0), + new S3(1), + new S3(0), + new S4(new S3(0), new S2(0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 0, 0, 0, 0, 1, 0)), 1, 0, new S1(0, 0, new S0(0, 0, 0, 0, 11829847737932804605UL, 0, 0), new S0(1, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(0, -2, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 9919258226402299883UL, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))), 0, new S0(0, 0, 0, 0, 0, 1, 0), 0), + new S2(0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(-1, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 1, 0), new S0(0, 0, 0, 0, 0, 0, 0))), + new S4(new S3(0), new S2(0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 0, 0, new S1(0, 1, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, -1, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(1, 0, 0, 0, 0, 0, 0))), 0, new S0(0, 0, 0, 0, 0, 1, 0), 0), + new S4(new S3(0), new S2(0, 0, new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), 0, 0, new S1(0, 0, new S0(1, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0)), new S1(0, 0, new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0), new S0(0, 0, 0, 0, 0, 0, 0))), 0, new S0(1, 0, 0, 0, 0, 0, 0), 0), + new S3(0), + new S3(0), + new S3(0) + }; + } +#pragma warning restore xUnit1013 + + private static void M75(S3 argThis, double arg1) + { + } +} + +public interface IRuntime +{ + void WriteLine(string site, T value); +} + +public class Runtime : IRuntime +{ + public void WriteLine(string site, T value) => System.Console.WriteLine(value); +} + +public class CollectibleALC : System.Runtime.Loader.AssemblyLoadContext +{ + public CollectibleALC() : base(true) + { + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.csproj new file mode 100644 index 0000000000000..de6d5e08882e8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_105619/Runtime_105619.csproj @@ -0,0 +1,8 @@ + + + True + + + + +