diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index b1dfa28f51720f..85bebf191cc2ec 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2196,7 +2196,9 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, } else { - if (emitter::emitIns_valid_imm_for_mov(imm, size)) + emitAttr immSize = EA_SIZE(size); + + if (emitter::emitIns_valid_imm_for_mov(imm, immSize)) { GetEmitter()->emitIns_R_I(INS_mov, size, reg, imm, INS_OPTS_NONE, INS_SCALABLE_OPTS_NONE DEBUGARG(targetHandle) DEBUGARG(gtFlags)); @@ -2214,7 +2216,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, // Determine whether movn or movz will require the fewest instructions to populate the immediate int preferMovn = 0; - for (int i = (size == EA_8BYTE) ? 48 : 16; i >= 0; i -= 16) + for (int i = (immSize == EA_8BYTE) ? 48 : 16; i >= 0; i -= 16) { if (uint16_t(imm >> i) == 0xffff) ++preferMovn; // a single movk 0xffff could be skipped if movn was used @@ -2229,7 +2231,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, // This can allow skipping filling a halfword uint16_t skipVal = (preferMovn > 0) ? 0xffff : 0; - unsigned bits = (size == EA_8BYTE) ? 64 : 32; + unsigned bits = (immSize == EA_8BYTE) ? 64 : 32; // Iterate over imm examining 16 bits at a time for (unsigned i = 0; i < bits; i += 16) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_132268/Runtime_132268.cs b/src/tests/JIT/Regression/JitBlue/Runtime_132268/Runtime_132268.cs new file mode 100644 index 00000000000000..2c2e116d3c7e1e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_132268/Runtime_132268.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Regression test for https://github.com/dotnet/runtime/issues/132268 +// +// Requires an arm64 AOT compilation (crossgen2/NativeAOT) to hit the byref constant path. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Xunit; + +namespace Runtime_132268; + +public unsafe class Runtime_132268 +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref byte GetNonNullPinnableReference(Span buffer) + { + return ref buffer.Length != 0 ? ref MemoryMarshal.GetReference(buffer) : ref Unsafe.AsRef((void*)1); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static int Consume(byte* p, int length) => p is null ? -1 : length; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int Pin(Span destination) + { + fixed (byte* p = &GetNonNullPinnableReference(destination)) + { + int status = Consume(p, destination.Length); + + if (status != 0) + { + throw new InvalidOperationException(); + } + + return status; + } + } + + [Fact] + public static void TestEntryPoint() + { + Assert.Equal(0, Pin(default)); + } +} diff --git a/src/tests/JIT/Regression/Regression_ro_2.csproj b/src/tests/JIT/Regression/Regression_ro_2.csproj index ecfbfd02be8a71..509acf83e4717a 100644 --- a/src/tests/JIT/Regression/Regression_ro_2.csproj +++ b/src/tests/JIT/Regression/Regression_ro_2.csproj @@ -128,6 +128,7 @@ +