Skip to content

Commit

Permalink
ARM-SVE: Fix validation logic for GatherVectorByteOffsetFirstFaultin…
Browse files Browse the repository at this point in the history
…g tests (dotnet#107165)
  • Loading branch information
amanasifkhalid authored and jtschuster committed Sep 17, 2024
1 parent 448343d commit 556477e
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 12 deletions.
10 changes: 4 additions & 6 deletions src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8958,7 +8958,7 @@ public static bool CheckGatherVectorBasesFirstFaultingBehavior<T, AddressT, Exte
return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorBasesResultByIndex<T, AddressT, ExtendedElementT>(i, mask, data) == result[i]);
}

public static bool CheckGatherVectorWithByteOffsetFirstFaultingBehavior<T, ExtendedElementT, Offset, TFault>(T[] mask, ExtendedElementT[] data, Offset[] offsets, T[] result, Vector<TFault> faultResult)
public static bool CheckGatherVectorWithByteOffsetFirstFaultingBehavior<T, ExtendedElementT, Offset, TFault>(T[] mask, byte[] data, Offset[] offsets, T[] result, Vector<TFault> faultResult)
where T : INumberBase<T>
where ExtendedElementT : INumberBase<ExtendedElementT>
where Offset : IBinaryInteger<Offset>
Expand All @@ -8971,6 +8971,7 @@ public static bool CheckGatherVectorWithByteOffsetFirstFaultingBehavior<T, Exten
return false;
}

var elemSize = Unsafe.SizeOf<ExtendedElementT>();
var hasFaulted = false;
var expectedFaultResult =
InitVector<TFault>(i =>
Expand All @@ -8986,8 +8987,7 @@ public static bool CheckGatherVectorWithByteOffsetFirstFaultingBehavior<T, Exten
}
var offset = int.CreateChecked(offsets[i]);
var endOffset = data.Length * Unsafe.SizeOf<ExtendedElementT>();
if (offset < 0 || offset >= endOffset)
if (offset < 0 || (offset + elemSize) > data.Length)
{
hasFaulted = true;
return TFault.Zero;
Expand All @@ -9000,9 +9000,7 @@ public static bool CheckGatherVectorWithByteOffsetFirstFaultingBehavior<T, Exten
return false;
}

byte[] bytes = new byte[data.Length * Unsafe.SizeOf<ExtendedElementT>()];
Buffer.BlockCopy(data, 0, bytes, 0, bytes.Length);
return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorResultByByteOffset<T, ExtendedElementT, Offset>(i, mask, bytes, offsets, result[i]));
return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorResultByByteOffset<T, ExtendedElementT, Offset>(i, mask, data, offsets, result[i]));
}

public static T[] CreateBreakPropagateMask<T>(T[] op1, T[] op2) where T : IBinaryInteger<T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ namespace JIT.HardwareIntrinsics.Arm
ref var op3Ref = ref op3;

Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateFirstFaultingResult(Unsafe.AsPointer(ref op1Ref), ref op2Ref, _dataTable.inBounded.Span.Length, Unsafe.AsPointer(ref op3Ref), _dataTable.outArrayPtr, faultResult);
ValidateFirstFaultingResult(Unsafe.AsPointer(ref op1Ref), Unsafe.AsPointer(ref op3Ref), _dataTable.outArrayPtr, faultResult);
}

public void RunBasicScenario_FalseMask()
Expand Down Expand Up @@ -718,24 +718,23 @@ namespace JIT.HardwareIntrinsics.Arm
}
}

private void ValidateFirstFaultingResult(void* op1, ref byte op2, int op2Size, void* op3, void* result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "")
private void ValidateFirstFaultingResult(void* op1, void* op3, void* result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Vector<{Op1BaseType}>.Count];
{Op2BaseType}[] inArray2 = new {Op2BaseType}[op2Size / Unsafe.SizeOf<{Op2BaseType}>()];
byte[] inArray2 = _dataTable.inBounded.Span.ToArray();
{Op3BaseType}[] inArray3 = new {Op3BaseType}[Vector<{Op3BaseType}>.Count];
{RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];

Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)(inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>()));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref op2, (uint)(inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>()));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)(inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>()));
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());

ValidateFirstFaultingResult(inArray1, inArray2, inArray3, outArray, faultResult, method);
}

private void ValidateFirstFaultingResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "")
private void ValidateFirstFaultingResult({Op1BaseType}[] firstOp, byte[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "")
{
var succeeded = Helpers.CheckGatherVectorWithByteOffsetFirstFaultingBehavior(firstOp, secondOp, thirdOp, result, faultResult);
var succeeded = Helpers.CheckGatherVectorWithByteOffsetFirstFaultingBehavior<{Op1BaseType}, {Op2BaseType}, {Op3BaseType}, {GetFfrType}>(firstOp, secondOp, thirdOp, result, faultResult);

if (!succeeded)
{
Expand Down

0 comments on commit 556477e

Please sign in to comment.