Skip to content

Commit

Permalink
[release/6.0] Disable folding small-typed returned indirections (#82846)
Browse files Browse the repository at this point in the history
* Normalize returns after optimizing returned indirs

This ensures we normalize returned indirs of locals, even when we fold
it into an access of a promoted local's field. This may change a signed
indir into access of an unsigned field, which may need a sign-extending
cast to be inserted.

It is not ideal that fgMorphRetInd can 'lose' this information, but
given that it is a specialized optimization it seems the simplest
solution is to just rely on the follow-up normalization.

Fix #61359

* Conservative fix

* Remove spurious diff

---------

Co-authored-by: Jakob Botsch Nielsen <[email protected]>
  • Loading branch information
github-actions[bot] and jakobbotsch authored Mar 10, 2023
1 parent 677c557 commit cbfaba5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14044,6 +14044,14 @@ GenTree* Compiler::fgMorphRetInd(GenTreeUnOp* ret)
// long<->double` there.
bool canFold = (indSize == lclVarSize) && (lclVarSize <= REGSIZE_BYTES);
#endif

// Avoid folding primitives to a struct-typed local for cases where we would maybe need to insert normalization on top.
// The backend does not correctly handle this for some promoted locals.
if (varTypeIsSmall(info.compRetType) && lclVar->TypeIs(TYP_STRUCT))
{
canFold = false;
}

// TODO: support `genReturnBB != nullptr`, it requires #11413 to avoid `Incompatible types for
// gtNewTempAssign`.
if (canFold && (genReturnBB == nullptr))
Expand Down
19 changes: 19 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_61359/Runtime_61359.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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;

public unsafe class Runtime_61359
{
public static int Main()
{
return HalfToInt16Bits((Half)(-1)) == -17408 ? 100 : -1;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static short HalfToInt16Bits(Half h)
{
return *(short*)&h;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit cbfaba5

Please sign in to comment.