diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 5dcf005afd7405..79bf3c16778df6 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1944,7 +1944,8 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou GenTreeHWIntrinsic* embOp2Node = intrin.op2->AsHWIntrinsic(); size_t numArgs = embOp2Node->GetOperandCount(); const HWIntrinsic intrinEmb(embOp2Node); - numArgs = embOp2Node->GetOperandCount(); + numArgs = embOp2Node->GetOperandCount(); + GenTree* prefUseNode = nullptr; if (HWIntrinsicInfo::IsFmaIntrinsic(intrinEmb.id)) { @@ -1961,44 +1962,15 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou unsigned resultOpNum = embOp2Node->GetResultOpNumForRmwIntrinsic(user, intrinEmb.op1, intrinEmb.op2, intrinEmb.op3); - GenTree* emitOp1 = intrinEmb.op1; - GenTree* emitOp2 = intrinEmb.op2; - GenTree* emitOp3 = intrinEmb.op3; - - if (resultOpNum == 2) - { - // op2 = op1 + (op2 * op3) - std::swap(emitOp1, emitOp3); - std::swap(emitOp1, emitOp2); - // op1 = (op1 * op2) + op3 - } - else if (resultOpNum == 3) + if (resultOpNum == 0) { - // op3 = op1 + (op2 * op3) - std::swap(emitOp1, emitOp3); - // op1 = (op1 * op2) + op3 + prefUseNode = embOp2Node->Op(1); } else { - // op1 = op1 + (op2 * op3) - // Nothing needs to be done + assert(resultOpNum >= 1 && resultOpNum <= 3); + prefUseNode = embOp2Node->Op(resultOpNum); } - - GenTree* ops[] = {intrinEmb.op1, intrinEmb.op2, intrinEmb.op3}; - for (GenTree* op : ops) - { - if (op == emitOp1) - { - tgtPrefUse = BuildUse(op); - srcCount++; - } - else if (op == emitOp2 || op == emitOp3) - { - srcCount += BuildDelayFreeUses(op, emitOp1); - } - } - - srcCount += BuildDelayFreeUses(intrin.op3, emitOp1); } else { @@ -2045,22 +2017,32 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou { prefUseOpNum = 2; } - GenTree* prefUseNode = embOp2Node->Op(prefUseOpNum); - for (size_t argNum = 1; argNum <= numArgs; argNum++) + prefUseNode = embOp2Node->Op(prefUseOpNum); + } + + for (size_t argNum = 1; argNum <= numArgs; argNum++) + { + GenTree* node = embOp2Node->Op(argNum); + + if (node == prefUseNode) { - if (argNum == prefUseOpNum) - { - tgtPrefUse = BuildUse(prefUseNode); - srcCount += 1; - } - else - { - srcCount += BuildDelayFreeUses(embOp2Node->Op(argNum), prefUseNode); - } + tgtPrefUse = BuildUse(node); + srcCount++; } + else + { + RefPosition* useRefPosition = nullptr; - srcCount += BuildDelayFreeUses(intrin.op3, prefUseNode); + int uses = BuildDelayFreeUses(node, nullptr, RBM_NONE, &useRefPosition); + srcCount += uses; + + // It is a hard requirement that these are not allocated to the same register as the destination, + // so verify no optimizations kicked in to skip setting the delay-free. + assert((useRefPosition != nullptr && useRefPosition->delayRegFree) || (uses == 0)); + } } + + srcCount += BuildDelayFreeUses(intrin.op3, prefUseNode); } else if (intrin.op2 != nullptr) { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106864/Runtime_106864.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106864/Runtime_106864.cs new file mode 100644 index 00000000000000..1faf1dd9a2a273 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106864/Runtime_106864.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 09:12:06 +// Run on Arm64 Windows +// Seed: 9639718980642677114-vectort,vector64,vector128,armsve +// Reduced from 52.6 KiB to 0.4 KiB in 00:00:26 +// Hits JIT assert in Release: +// Assertion failed 'targetReg != embMaskOp2Reg' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Generate code' (IL size 32; hash 0xade6b36b; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\hwintrinsiccodegenarm64.cpp Line: 818 +// +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public class C1 +{ + public Vector F1; +} + +public class Runtime_106864 +{ + public static C1 s_2 = new C1(); + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + C1 vr2 = s_2; + var vr3 = vr2.F1; + var vr4 = vr2.F1; + vr2.F1 = Sve.Max(vr3, vr4); + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106864/Runtime_106864.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106864/Runtime_106864.csproj new file mode 100644 index 00000000000000..1352ebe3277bc7 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106864/Runtime_106864.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867.cs new file mode 100644 index 00000000000000..1d106ce17aa3bd --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:10:06 +// Run on Arm64 Windows +// Seed: 13584223539078280353-vectort,vector64,vector128,armsve +// Reduced from 87.4 KiB to 0.8 KiB in 00:00:52 +// Hits JIT assert in Release: +// Assertion failed 'secondId->idReg1() != secondId->idReg4()' in 'S0:M6(ubyte,double):this' during 'Emit code' (IL size 81; hash 0x596acd7c; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\emitarm64sve.cpp Line: 18601 +// +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public struct S0 +{ + public void M6(byte arg0, double arg1) + { + var vr0 = Vector128.CreateScalar(119.12962f).AsVector(); + var vr3 = Runtime_106867.s_2; + var vr4 = Vector128.CreateScalar(1f).AsVector(); + var vr5 = Runtime_106867.s_2; + var vr2 = Sve.FusedMultiplySubtractNegated(vr3, vr4, vr5); + if ((Sve.ConditionalExtractLastActiveElement(vr0, 0, vr2) < 0)) + { + this = this; + } + } +} + +public class Runtime_106867 +{ + public static Vector s_2; + public static double[] s_5 = new double[] + { + 0 + }; + public static byte s_16; + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + var vr6 = s_5[0]; + new S0().M6(s_16, vr6); + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867.csproj new file mode 100644 index 00000000000000..1352ebe3277bc7 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867_1.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867_1.cs new file mode 100644 index 00000000000000..e5e05cc6553bcc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867_1.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; +using System.Runtime.CompilerServices; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:12:51 +// Run on Arm64 Windows +// Seed: 4576767951799510057-vectort,vector64,vector128,armsve +// Reduced from 32.2 KiB to 0.5 KiB in 00:00:25 +// Hits JIT assert in Release: +// Assertion failed 'secondId->idReg1() != secondId->idReg3()' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Emit code' (IL size 55; hash 0xade6b36b; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\emitarm64sve.cpp Line: 18600 +// +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public class Runtime_106866_2 +{ + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + Vector vr4 = default(Vector); + vr4 = Sve.MultiplyAdd(vr4, vr4, vr4); + var vr5 = (short)0; + var vr6 = Vector128.CreateScalar(vr5).AsVector(); + var vr7 = (short)0; + var vr8 = Sve.ConditionalExtractLastActiveElement(vr6, vr7, vr4); + Consume(vr8); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Consume(T val) + { + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867_1.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867_1.csproj new file mode 100644 index 00000000000000..1352ebe3277bc7 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867_1.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + +