Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/mono/mono/mini/interp/transform-opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3849,9 +3849,12 @@ interp_super_instructions (TransformData *td)
if (def->opcode != MINT_DEF_ARG && def->opcode != MINT_PHI && def->opcode != MINT_DEF_TIER_VAR &&
!(def->flags & INTERP_INST_FLAG_PROTECTED_NEWOBJ)) {
int dreg = ins->dreg;
if (var_has_indirects (td, dreg)) {
// Don't bother with indirect locals
}
Comment thread
lateralusX marked this conversation as resolved.
// if var is not ssa or it is a renamed fixed, then we can't replace the dreg
// since there can be conflicting liveness, unless the instructions are adjacent
if ((var_is_ssa_form (td, dreg) && !td->vars [dreg].renamed_ssa_fixed) ||
else if ((var_is_ssa_form (td, dreg) && !td->vars [dreg].renamed_ssa_fixed) ||
interp_prev_ins (ins) == def) {
def->dreg = dreg;

Expand Down
70 changes: 70 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_122237/Runtime_122237.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Runtime_122237;

using Xunit;

// Self-reassignment through a constructor whose `in` (byref) parameters alias the
// destination: `a = new GEJ(a.x, a.y, a.z, a.infinity)`. Per the ECMA-335 semantics of
// `newobj`, the object must be constructed into a temporary and only then copied to `a`,
// so the constructor observes the *old* value of `a` through the `in` pointers. A copy
// elimination that forwards the constructed value directly into the address-taken `a`
// would make the constructor read the storage it is simultaneously writing, zeroing the
// fields. The loop runs long enough to reach the Mono interpreter's optimized tier.
public readonly struct FE
{
public readonly uint n0, n1, n2, n3, n4, n5, n6, n7, n8, n9;
public readonly int magnitude;
public readonly bool normalized;

public FE(uint a0, uint a1, uint a2, uint a3, uint a4, uint a5, uint a6, uint a7, uint a8, uint a9)
{
n0 = a0; n1 = a1; n2 = a2; n3 = a3; n4 = a4;
n5 = a5; n6 = a6; n7 = a7; n8 = a8; n9 = a9;
magnitude = 1;
normalized = true;
}
}

public readonly struct GEJ
{
public readonly FE x, y, z;
public readonly bool infinity;

public GEJ(in FE x, in FE y, in FE z, bool infinity)
{
this.x = x;
this.y = y;
this.z = z;
this.infinity = infinity;
}
}

public class Runtime_122237
{
[Fact]
public static void TestEntryPoint()
{
var a = new GEJ(
new FE(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
new FE(11, 22, 33, 44, 55, 66, 77, 88, 99, 11),
new FE(21, 22, 23, 24, 25, 26, 27, 28, 29, 210),
false);

uint expected = a.x.n0;

int firstBad = -1;
for (int i = 0; i < 5000; i++)
{
a = new GEJ(a.x, a.y, a.z, a.infinity);
if (a.x.n0 != expected)
{
firstBad = i;
break;
}
}

Assert.Equal(-1, firstBad);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>
Loading