diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 49f67585225024..04310d7e350f42 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -2555,7 +2555,11 @@ CodeGen::GenIntCastDesc::GenIntCastDesc(GenTreeCast* cast) if (castIsLoad) { - const var_types srcLoadType = src->TypeGet(); + // A spill temp holds the full actual-type value, already extended per the source's own + // signedness, so it must be reloaded as that actual type rather than as a small memory + // operand -- otherwise a signed small source (e.g. TYP_BYTE) reloaded under a zero-extending + // cast would drop the sign bits it actually holds. + const var_types srcLoadType = src->isUsedFromSpillTemp() ? srcType : src->TypeGet(); switch (m_extendKind) { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_124508/Runtime_124508.cs b/src/tests/JIT/Regression/JitBlue/Runtime_124508/Runtime_124508.cs new file mode 100644 index 00000000000000..e5f91f11e5e8c1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_124508/Runtime_124508.cs @@ -0,0 +1,281 @@ +// 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 v3.3 on 2026-02-15 18:01:33 +// Seed: 12192374036514626124 +// +// A signed small load (sbyte[] element, materialized via movsx) that feeds a +// zero-extending cast to ushort could be spilled by LSRA under high register +// pressure (x86, FullOpts). GenIntCastDesc reloaded the spill temp as the small +// signed type, which asserted (and would have emitted a 1-byte movzx that drops +// the sign bits the temp actually holds) instead of reloading the full 4-byte +// actual type. Compiling M3 exercises the shape (in the switch's case 4). + +namespace Runtime_124508; + +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public class Runtime_124508 +{ + public static IRuntime s_rt; + public static sbyte[] s_1; + public static long s_3; + public static byte s_4; + public static Vector256 s_5; + public static ulong s_8; + public static byte s_12; + public static int s_13; + public static uint s_15; + public static uint s_16; + public static Vector256[] s_17; + public static ulong[] s_18; + public static Vector128 s_23 = Vector128.Create(0, 1U, 0, 0); + + [Fact] + public static void TestEntryPoint() + { + s_rt = new Runtime(); + try + { + M3(); + } + catch { } + } + + public static ushort M3() + { + Vector128[] var1 = default(Vector128[]); + uint var5 = default(uint); + Vector256 var7 = default(Vector256); + Vector128 var9 = default(Vector128); + uint var15 = default(uint); + Vector var18 = default(Vector); + sbyte[] var19 = default(sbyte[]); + byte var3 = 0; + Vector[] var4 = new Vector[] + { + Vector.Create(0) + }; + s_rt.WriteLine(var5); + try + { + throw new System.Exception(); + } + catch (System.NotSupportedException) + { + var1 = new Vector128[] + { + Vector128.Create(0) + }; + } + catch (System.NotImplementedException) + { + s_rt.WriteLine(var7); + } + catch (System.InvalidOperationException) + { + ulong var8 = s_8; + s_rt.WriteLine(var9); + long var10 = 0; + s_rt.WriteLine(var8); + s_rt.WriteLine(var10); + } + catch (System.ArgumentOutOfRangeException) + { + uint[][][] var11 = new uint[][][] + { + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 }, + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 }, + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 }, + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 }, + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 }, + new uint[] { 0 } + }, + new uint[][] + { + new uint[] { 0 }, + new uint[] { 0 } + } + }; + s_rt.WriteLine(var11[0][0][0]); + } + catch (System.ArgumentNullException) + { + short var12 = 0; + Vector256 var13 = s_5; + s_rt.WriteLine(var12); + s_rt.WriteLine(var13); + } + catch (System.Exception) + { + s_1[0] >>= (int)Bmi1.BitFieldExtract(0, 0, var3); + Vector128.Create(s_3); + } + + s_rt.WriteLine(var3); + ushort[] var16 = new ushort[] + { + 0 + }; + var vr4 = var1[0]; + Sse2.CompareLessThan(vr4, Vector128.Create((short)Bmi2.ParallelBitExtract(var15, var15))); + s_rt.WriteLine(var16[0]); + var1[0] = var1[0]; + switch (s_13--) + { + case 0: + { + s_16 += M5(); + Vector.Create(s_12); + s_rt.WriteLine(var18); + s_rt.WriteLine(var19[0]); + var vr1 = (byte)M11(); + Vector128.Create(vr1); + } + + break; + case 1: + { + Vector256[] var20 = s_17; + ulong[] var21 = s_18; + s_rt.WriteLine(var20[0]); + s_rt.WriteLine(var21[0]); + } + + break; + case -1: + { + sbyte var22 = s_1[0]++; + Vector128[,, ] var25 = new Vector128[,, ] + { + { + { + Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0) + } + } + }; + sbyte var26 = var22; + s_17[0] = s_17[0]; + var vr3 = s_4++; + var vr0 = M5(); + M9(vr0, (byte)Bmi2.ParallelBitExtract(s_15, (uint)Sse2.MoveMask(Vector128.CreateScalar((byte)0))), s_8--); + s_rt.WriteLine(var25[0, 0, 0]); + s_rt.WriteLine(var26); + s_rt.WriteLine(var22); + } + + break; + case 3: + { + } + + break; + case 4: + { + s_17[0] = s_17[0]; + Vector128 var33 = Vector128.Create(0, 0, 0, 0); + bool var34 = -1 <= M11(); + var1[0] = Vector128.CreateScalar((short)(s_1[0] << (0 >> (ushort)M9(0, 0, 0)))); + var1 = new Vector128[] + { + Vector128.Create(0) + }; + s_rt.WriteLine(var33); + s_rt.WriteLine(var34); + } + + break; + case 5: + { + } + + break; + case 6: + { + } + + break; + case 7: + { + } + + break; + default: + { + } + + break; + } + + var vr6 = Vector128.CreateScalar(0); + var vr5 = (uint)Sse41.Extract(vr6, 0); + return (ushort)Bmi2.ZeroHighBits(vr5, 0); + } + + public static ushort M5() + { + return default(ushort); + } + + public static long M9(ushort arg0, byte arg1, ulong arg2) + { + return s_3; + } + + public static long M11() + { + var vr2 = Vector256.Create(-2); + Avx512F.VL.ConvertToVector128Int16(vr2); + return 7708512004982082393L; + } +} + +public interface IRuntime +{ + void WriteLine(T value); +} + +public class Runtime : IRuntime +{ + public void WriteLine(T value) => System.Console.WriteLine(value); +} diff --git a/src/tests/JIT/Regression/Regression_ro_1.csproj b/src/tests/JIT/Regression/Regression_ro_1.csproj index b332ffd68aeac6..6ce2fb8e85386e 100644 --- a/src/tests/JIT/Regression/Regression_ro_1.csproj +++ b/src/tests/JIT/Regression/Regression_ro_1.csproj @@ -78,6 +78,7 @@ +