diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index b8752042b1c72f..46137c227399d2 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -3433,7 +3433,6 @@ void Lowering::LowerRetSingleRegStructLclVar(GenTreeUnOp* ret) if (varDsc->lvDoNotEnregister) { - assert(!replacedInLowering); lclVar->ChangeOper(GT_LCL_FLD); lclVar->AsLclFld()->SetLclOffs(0); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_58972/Runtime_58972.cs b/src/tests/JIT/Regression/JitBlue/Runtime_58972/Runtime_58972.cs new file mode 100644 index 00000000000000..b63c1d907f14c1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_58972/Runtime_58972.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public class Runtime_58972 +{ + public static int Main() + { + GetItem(new MyStruct[1], 0); + return 100; + } + + // This code results in a struct returned in register where we replace the local + // of type MyStruct by its only field, and where that field cannot be enregistered. + // We would potentially miss normalization if the struct was returned as an integer + // type and hit a defensive assertion because of it. + static MyStruct GetItem(MyStruct[] a, int i) + { + try + { + return a[i]; + } + catch (IndexOutOfRangeException) + { + ThrowHelper(); + return default; + } + } + + static void ThrowHelper() => throw new Exception(); + + struct MyStruct + { + byte b; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_58972/Runtime_58972.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_58972/Runtime_58972.csproj new file mode 100644 index 00000000000000..f3e1cbd44b4041 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_58972/Runtime_58972.csproj @@ -0,0 +1,12 @@ + + + Exe + + + None + True + + + + +