diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 10aabca3a453c..39d2328c2e8d6 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -7539,6 +7539,15 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk) } break; +#ifdef FEATURE_HW_INTRINSICS + case GT_HWINTRINSIC: + if (tree->AsHWIntrinsic()->OperIsMemoryStore()) + { + memoryHavoc |= memoryKindSet(GcHeap, ByrefExposed); + } + break; +#endif // FEATURE_HW_INTRINSICS + case GT_LOCKADD: case GT_XORR: case GT_XAND: @@ -7547,7 +7556,6 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk) case GT_CMPXCHG: case GT_MEMORYBARRIER: { - assert(!tree->OperIs(GT_LOCKADD) && "LOCKADD should not appear before lowering"); memoryHavoc |= memoryKindSet(GcHeap, ByrefExposed); } break; @@ -7587,6 +7595,7 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk) default: // All other gtOper node kinds, leave 'memoryHavoc' unchanged (i.e. false) + assert(!tree->OperRequiresAsgFlag()); break; } } diff --git a/src/tests/JIT/opt/Loops/LoopSideEffectsForHwiStores.cs b/src/tests/JIT/opt/Loops/LoopSideEffectsForHwiStores.cs new file mode 100644 index 0000000000000..b07f347e6c124 --- /dev/null +++ b/src/tests/JIT/opt/Loops/LoopSideEffectsForHwiStores.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics.Arm; + +unsafe class LoopSideEffectsForHwiStores +{ + public static int Main() + { + static bool VerifyExpectedVtor(Vector128 a) => a.Equals(Vector128.Create(4)); + + var a = new ClassWithVtor(); + + fixed (Vector128* p = &a.VtorField) + { + if (Sse2.IsSupported && !VerifyExpectedVtor(ProblemWithSse2(a, (byte*)p))) + { + System.Console.WriteLine("ProblemWithSse2 failed!"); + return 101; + } + + if (AdvSimd.IsSupported && !VerifyExpectedVtor(ProblemWithAdvSimd(a, (byte*)p))) + { + System.Console.WriteLine("ProblemWithAdvSimd failed!"); + return 101; + } + } + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe Vector128 ProblemWithSse2(ClassWithVtor a, byte* p) + { + Vector128 vtor = Vector128.Zero; + + a.VtorField = Vector128.Create(1); + a.VtorField = Sse2.Add(a.VtorField, a.VtorField); + + for (int i = 0; i < 10; i++) + { + vtor = Sse2.Add(vtor, Sse2.Add(a.VtorField, a.VtorField)); + Sse2.Store(p, Vector128.Zero); + } + + return vtor; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe Vector128 ProblemWithAdvSimd(ClassWithVtor a, byte* p) + { + Vector128 vtor = Vector128.Zero; + + a.VtorField = Vector128.Create(1); + a.VtorField = AdvSimd.Add(a.VtorField, a.VtorField); + + for (int i = 0; i < 10; i++) + { + vtor = AdvSimd.Add(vtor, AdvSimd.Add(a.VtorField, a.VtorField)); + AdvSimd.Store(p, Vector128.Zero); + } + + return vtor; + } + + class ClassWithVtor + { + public Vector128 VtorField; + } +} diff --git a/src/tests/JIT/opt/Loops/LoopSideEffectsForHwiStores.csproj b/src/tests/JIT/opt/Loops/LoopSideEffectsForHwiStores.csproj new file mode 100644 index 0000000000000..7e343802d9e7a --- /dev/null +++ b/src/tests/JIT/opt/Loops/LoopSideEffectsForHwiStores.csproj @@ -0,0 +1,14 @@ + + + Exe + true + 1 + + + PdbOnly + True + + + + +