From 67dbbeb7c2392fa53c621fe2ad5eb5c197475659 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Tue, 19 Sep 2023 11:30:38 -0700 Subject: [PATCH] JIT: add missing xarch RMW case (#92252) Handle the case where we're indirectly updating a local with a value that is not a constant. Fixes #92218. --- src/coreclr/jit/emitxarch.cpp | 7 ++++ .../JitBlue/Runtime_92218/Runtime_92218.cs | 40 +++++++++++++++++++ .../Runtime_92218/Runtime_92218.csproj | 8 ++++ 3 files changed, 55 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index ba599c9e465ad..c1d7e2df5d423 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -5485,6 +5485,13 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI { assert(!src->isContained()); // there must be one non-contained src + if (addr->isContained() && addr->OperIs(GT_LCL_ADDR)) + { + GenTreeLclVarCommon* lclVar = addr->AsLclVarCommon(); + emitIns_S_R(ins, attr, src->GetRegNum(), lclVar->GetLclNum(), lclVar->GetLclOffs()); + return; + } + // ind, reg id = emitNewInstrAmd(attr, offset); emitHandleMemOp(storeInd, id, emitInsModeFormat(ins, IF_ARD_RRD), ins); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.cs b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.cs new file mode 100644 index 0000000000000..9b4696e31fc16 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.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 System; +using System.Runtime.CompilerServices; +using System.Threading; +using Xunit; + +public struct MutableStruct +{ + private long _internalValue; + + public long InternalValue + { + get => Volatile.Read(ref _internalValue); + private set => Volatile.Write(ref _internalValue, value); + } + + public void Add(long value) => AddInternal(value); + private void AddInternal(long value) => InternalValue += value; + public MutableStruct(long value) => InternalValue = value; +} + +public static class Runtime_92218 +{ + [Fact] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static void Problem() + { + var test = new MutableStruct(420); + var from = new MutableStruct(42); + + var wrapper = -new TimeSpan(3); + + while (test.InternalValue >= from.InternalValue) + { + test.Add(wrapper.Ticks); + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj new file mode 100644 index 0000000000000..15edd99711a1a --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file