Skip to content

Commit aa7c7ff

Browse files
[release/8.0-staging] JIT: Fixed incorrect reversed condition for GT (#100372)
* Fixed incorrect reversed condition for GT * Added test case * Remove comment * Use JitStressModeNames * Cleaned up test * Update Runtime_92201.csproj --------- Co-authored-by: TIHan <[email protected]>
1 parent 88be910 commit aa7c7ff

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed

src/coreclr/jit/gentree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8635,7 +8635,7 @@ struct GenCondition
86358635
NONE, NONE, SGE, SGT, SLT, SLE, NS, S,
86368636
NE, EQ, UGE, UGT, ULT, ULE, NC, C,
86378637
FNEU, FEQU, FGEU, FGTU, FLTU, FLEU, NO, O,
8638-
FNE, FEQ, FGE, FGT, FLT, FGT, NP, P
8638+
FNE, FEQ, FGE, FGT, FLT, FLE, NP, P
86398639
};
86408640
// clang-format on
86418641

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
7+
using System.Runtime.Intrinsics;
8+
using Xunit;
9+
10+
namespace JIT.HardwareIntrinsics.General._Vector128
11+
{
12+
public static partial class Program
13+
{
14+
[Fact]
15+
public static void Test()
16+
{
17+
var test = new VectorBooleanBinaryOpTest__LessThanOrEqualAnySingle();
18+
19+
// Validates basic functionality works, using Unsafe.Read
20+
test.RunBasicScenario_UnsafeRead();
21+
22+
if (!test.Succeeded)
23+
{
24+
throw new Exception("One or more scenarios did not complete as expected.");
25+
}
26+
}
27+
}
28+
29+
public sealed unsafe class VectorBooleanBinaryOpTest__LessThanOrEqualAnySingle
30+
{
31+
private struct DataTable
32+
{
33+
private byte[] inArray1;
34+
private byte[] inArray2;
35+
36+
private GCHandle inHandle1;
37+
private GCHandle inHandle2;
38+
39+
private ulong alignment;
40+
41+
public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
42+
{
43+
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
44+
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
45+
if (!int.IsPow2(alignment) || (alignment > 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
46+
{
47+
throw new ArgumentException("Invalid value of alignment");
48+
}
49+
50+
this.inArray1 = new byte[alignment * 2];
51+
this.inArray2 = new byte[alignment * 2];
52+
53+
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
54+
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
55+
56+
this.alignment = (ulong)alignment;
57+
58+
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
59+
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
60+
}
61+
62+
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
63+
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
64+
65+
public void Dispose()
66+
{
67+
inHandle1.Free();
68+
inHandle2.Free();
69+
}
70+
71+
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
72+
{
73+
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
74+
}
75+
}
76+
77+
private static readonly int LargestVectorSize = 16;
78+
79+
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
80+
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
81+
82+
private static Single[] _data1 = new Single[Op1ElementCount];
83+
private static Single[] _data2 = new Single[Op2ElementCount];
84+
85+
private DataTable _dataTable;
86+
87+
public VectorBooleanBinaryOpTest__LessThanOrEqualAnySingle()
88+
{
89+
Succeeded = true;
90+
91+
_data1[0] = 0.168625f;
92+
_data1[1] = 0.5899811f;
93+
_data1[2] = 0.8042229f;
94+
_data1[3] = 0.8173325f;
95+
96+
_data2[0] = 0.059660614f;
97+
_data2[1] = 0.13952714f;
98+
_data2[2] = 0.23523656f;
99+
_data2[3] = 0.48773053f;
100+
101+
_dataTable = new DataTable(_data1, _data2, LargestVectorSize);
102+
}
103+
104+
public bool Succeeded { get; set; }
105+
106+
[MethodImpl(MethodImplOptions.NoInlining)]
107+
public bool LessThanOrEqualAnyProblem()
108+
{
109+
return Vector128.LessThanOrEqualAny(
110+
Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr),
111+
Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr)
112+
);
113+
}
114+
115+
[MethodImpl(MethodImplOptions.NoInlining)]
116+
public void* GetPtr1()
117+
{
118+
return _dataTable.inArray1Ptr;
119+
}
120+
121+
[MethodImpl(MethodImplOptions.NoInlining)]
122+
public void* GetPtr2()
123+
{
124+
return _dataTable.inArray2Ptr;
125+
}
126+
127+
[MethodImpl(MethodImplOptions.NoInlining)]
128+
public void CheckResult(bool result)
129+
{
130+
ValidateResult(GetPtr1(), GetPtr2(), result);
131+
}
132+
133+
public void RunBasicScenario_UnsafeRead()
134+
{
135+
var result = Vector128.LessThanOrEqualAny(
136+
Unsafe.Read<Vector128<Single>>(GetPtr1()),
137+
Unsafe.Read<Vector128<Single>>(GetPtr2())
138+
);
139+
140+
CheckResult(result);
141+
}
142+
143+
[MethodImpl(MethodImplOptions.NoInlining)]
144+
private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
145+
{
146+
Single[] inArray1 = new Single[Op1ElementCount];
147+
Single[] inArray2 = new Single[Op2ElementCount];
148+
149+
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
150+
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
151+
152+
ValidateResult(inArray1, inArray2, result, method);
153+
}
154+
155+
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
156+
{
157+
bool succeeded = true;
158+
159+
var expectedResult = false;
160+
161+
for (var i = 0; i < Op1ElementCount; i++)
162+
{
163+
expectedResult |= (left[i] <= right[i]);
164+
}
165+
166+
succeeded = (expectedResult == result);
167+
168+
if (!succeeded)
169+
{
170+
Succeeded = false;
171+
}
172+
}
173+
}
174+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Optimize>True</Optimize>
4+
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="$(MSBuildProjectName).cs" />
8+
9+
<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="0" />
10+
<CLRTestEnvironmentVariable Include="DOTNET_EnableHWIntrinsic" Value="0" />
11+
<CLRTestEnvironmentVariable Include="DOTNET_JitStressModeNames" Value="STRESS_BB_PROFILE STRESS_REVERSE_FLAG" />
12+
</ItemGroup>
13+
</Project>

0 commit comments

Comments
 (0)