Skip to content

Commit

Permalink
Feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
TIHan committed Jun 24, 2024
1 parent b6b574a commit c84567a
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 66 deletions.
1 change: 1 addition & 0 deletions src/coreclr/jit/emitarm64sve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2727,6 +2727,7 @@ void emitter::emitInsSve_R_R_I(instruction ins,
if (sopt == INS_SCALABLE_OPTS_WITH_VECTOR_PAIR)
{
fmt = IF_SVE_BQ_2A;
unreached(); // Not supported yet.
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/hwintrinsiccodegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2112,7 +2112,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
{
assert(targetReg != op2Reg);

GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true);
GetEmitter()->emitIns_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, op1Reg);
}

HWIntrinsicImmOpHelper helper(this, intrin.op3, node);
Expand Down

Large diffs are not rendered by default.

37 changes: 2 additions & 35 deletions src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,13 @@ namespace JIT.HardwareIntrinsics.Arm
{
static class Helpers
{
public static Vector<T> CreateAndFillMaskFromFirstElement<T>(T value) where T: unmanaged
public static Vector<T> InitVector<T>(Func<int, T> f)
{
var count = Vector<T>.Count;
var arr = new T[count];
for (var i = 0; i < count; i++)
{
arr[i] = value;
}
return new Vector<T>(arr);
}

public static Vector<T> CreateAndFillMaskFromSecondElement<T>(T value) where T: unmanaged
{
var count = Vector<T>.Count;
var arr = new T[count];
for (var i = 1; i < count; i++)
{
arr[i] = value;
}
return new Vector<T>(arr);
}

public static Vector<T> CreateAndFillMaskFromLastElement<T>(T value) where T: unmanaged
{
var count = Vector<T>.Count;
var arr = new T[count];
for (var i = count - 1; i >= 0; i--)
{
arr[i] = value;
}
return new Vector<T>(arr);
}

public static Vector<T> CreateAndFillMaskFromSecondToLastElement<T>(T value) where T: unmanaged
{
var count = Vector<T>.Count;
var arr = new T[count];
for (var i = count - 2; i >= 0; i--)
{
arr[i] = value;
arr[i] = f(i);
}
return new Vector<T>(arr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ namespace JIT.HardwareIntrinsics.Arm
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
test.RunBasicScenario_Load_Wrapper();
test.RunBasicScenario_Load_WrapperWithIndex();
}

// Validates calling via reflection works, using Unsafe.Read
Expand Down Expand Up @@ -206,6 +208,46 @@ namespace JIT.HardwareIntrinsics.Arm
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}

[MethodImpl(MethodImplOptions.NoInlining)]
{RetVectorType}<{RetBaseType}> Wrapper<T>()
{
return {Isa}.{Method}(
{LoadIsa}.Load{Op1VectorType}(Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All), ({Op1BaseType}*)(_dataTable.inArray1Ptr)),
{LoadIsa}.Load{Op2VectorType}(Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All), ({Op2BaseType}*)(_dataTable.inArray2Ptr)),
{ElementIndex}
);
}

public void RunBasicScenario_Load_Wrapper()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load_Wrapper));

var result = Wrapper<{RetBaseType}>();

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}

[MethodImpl(MethodImplOptions.NoInlining)]
{RetVectorType}<{RetBaseType}> WrapperWithIndex<T>(byte index)
{
return {Isa}.{Method}(
{LoadIsa}.Load{Op1VectorType}(Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All), ({Op1BaseType}*)(_dataTable.inArray1Ptr)),
{LoadIsa}.Load{Op2VectorType}(Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All), ({Op2BaseType}*)(_dataTable.inArray2Ptr)),
index
);
}

public void RunBasicScenario_Load_WrapperWithIndex()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load_WrapperWithIndex));

var result = WrapperWithIndex<{RetBaseType}>(ElementIndex);

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}

public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
Expand Down
30 changes: 30 additions & 0 deletions src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveTestTest.template
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,36 @@ namespace JIT.HardwareIntrinsics.Arm
}
}

/// Find any occurrence where both left and right and set
static bool TestAnyTrue(Vector<{MaskBaseType}> left, Vector<{MaskBaseType}> right)
{
for (var i = 0; i < Vector<{MaskBaseType}>.Count; i++)
{
if ((left[i] > 0) && (right[i] > 0)) return true;
}
return false;
}

/// Find first true value in left, and return contents of right
static bool TestFirstTrue(Vector<{MaskBaseType}> left, Vector<{MaskBaseType}> right)
{
for (var i = 0; i < Vector<{MaskBaseType}>.Count; i++)
{
if (left[i] > 0) return (right[i] > 0) ? true : false;
}
return false;
}

/// Find last true value in left, and return contents of right
static bool TestLastTrue(Vector<{MaskBaseType}> left, Vector<{MaskBaseType}> right)
{
for (var i = Vector<{MaskBaseType}>.Count - 1; i > 0; i--)
{
if (left[i] > 0) return (right[i] > 0) ? true : false;
}
return false;
}

private void ValidateResult(Vector<{MaskBaseType}> op1, Vector<{MaskBaseType}> op2, bool result, [CallerMemberName] string method = "")
{
bool succeeded = true;
Expand Down

0 comments on commit c84567a

Please sign in to comment.