Skip to content

Some hardware intrinsic nodes can reorder side effects #54956

@SingleAccretion

Description

@SingleAccretion

Reproduction:

using System.Numerics;
using System.Runtime.CompilerServices;

SideEffects(null, new Vector<int>[] { });

[MethodImpl(MethodImplOptions.NoInlining)]
static Vector<int> SideEffects(Vector<int>* a, Vector<int>[] b)
{
    var v = Vector.AndNot(*a, b[0]);

    return v;
}

Actual result:

> dotnet run
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.

Expected result:

> dotnet run
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.

This happens because of this code:

if (SimdAsHWIntrinsicInfo::NeedsOperandsSwapped(intrinsic))
{
std::swap(op1, op2);
}

Which does not account for side effects. Important note: since the importation code does not propagate the side effect flags properly (yet), they cannot be relied on when determining whether it is safe to swap at that point.

Possible solutions:

  1. Aggressively spill to temps - bad from CQ & TP standpoints.
  2. Use GTF_REVERSE_OPS - bad from the standpoint that this flag should be removed.
  3. Fix the operands up in LIR, where the tree walk no longer determines the execution order - probably cleanest but also most complex solution.

Note: the problematic code will become less centralized after #53450 is merged. See my review notes over there.

Metadata

Metadata

Assignees

Labels

Priority:3Work that is nice to havearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions