Skip to content

Commit 5aa61cc

Browse files
Copilotagocke
andcommitted
Add unit test for NaN normalization in ildasm output
Co-authored-by: agocke <515774+agocke@users.noreply.github.com>
1 parent 61eccfc commit 5aa61cc

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
.assembly extern System.Runtime { }
5+
.assembly FloatSpecialValues { }
6+
7+
.class public auto ansi beforefieldinit TestFloatSpecialValues
8+
extends [System.Runtime]System.Object
9+
{
10+
// Test NaN values - these should output with normalized "// -nan" comment
11+
.field public static literal float64 NaNValue = float64(0xFFF8000000000000)
12+
13+
// Test infinity values for completeness
14+
.field public static literal float64 PositiveInf = float64(0x7FF0000000000000)
15+
.field public static literal float64 NegativeInf = float64(0xFFF0000000000000)
16+
17+
// Test float32 NaN as well
18+
.field public static literal float32 NaNValue32 = float32(0xFFC00000)
19+
20+
.method public hidebysig specialname rtspecialname
21+
instance void .ctor() cil managed
22+
{
23+
.maxstack 8
24+
ldarg.0
25+
call instance void [System.Runtime]System.Object::.ctor()
26+
ret
27+
}
28+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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.Diagnostics;
6+
using System.IO;
7+
using System.Text.RegularExpressions;
8+
using Xunit;
9+
10+
public class FloatSpecialValuesTests : IDisposable
11+
{
12+
private string _ilasmFile;
13+
private string _ildasmFile;
14+
15+
public FloatSpecialValuesTests()
16+
{
17+
string coreRoot = Environment.GetEnvironmentVariable("CORE_ROOT");
18+
if (string.IsNullOrWhiteSpace(coreRoot))
19+
{
20+
Console.WriteLine("Environment variable is not set: 'CORE_ROOT'");
21+
throw new InvalidOperationException("Environment variable is not set: 'CORE_ROOT'");
22+
}
23+
if (!Directory.Exists(coreRoot))
24+
{
25+
Console.WriteLine($"Did not find CORE_ROOT directory: {coreRoot}");
26+
throw new InvalidOperationException("Did not find CORE_ROOT directory");
27+
}
28+
29+
var nativeExeExtensions = new string[] { string.Empty, ".exe" };
30+
bool found = false;
31+
string ilasmFile = null;
32+
string ildasmFile = null;
33+
foreach (string nativeExeExtension in nativeExeExtensions)
34+
{
35+
ilasmFile = Path.Combine(coreRoot, $"ilasm{nativeExeExtension}");
36+
ildasmFile = Path.Combine(coreRoot, $"ildasm{nativeExeExtension}");
37+
if (File.Exists(ilasmFile) && File.Exists(ildasmFile))
38+
{
39+
found = true;
40+
break;
41+
}
42+
}
43+
if (!found)
44+
{
45+
Console.WriteLine($"Did not find ilasm or ildasm in CORE_ROOT directory: {coreRoot}");
46+
throw new InvalidOperationException("Did not find ilasm or ildasm in CORE_ROOT directory");
47+
}
48+
49+
_ilasmFile = ilasmFile;
50+
_ildasmFile = ildasmFile;
51+
}
52+
53+
[Fact]
54+
public void NaNOutputIsNormalizedAcrossPlatforms()
55+
{
56+
Console.WriteLine("NaNOutputIsNormalizedAcrossPlatforms");
57+
58+
string ilFileName = "FloatSpecialValues.il";
59+
string disasmIlFileName;
60+
ProcessStartInfo ilasmPsi, ildasmPsi;
61+
GetIlasmProcessStartInfos(_ilasmFile, _ildasmFile, ilFileName, out disasmIlFileName, out ilasmPsi, out ildasmPsi);
62+
63+
Process ilasmProcess = Process.Start(ilasmPsi);
64+
ilasmProcess.WaitForExit();
65+
Assert.Equal(0, ilasmProcess.ExitCode);
66+
67+
Process ildasmProcess = Process.Start(ildasmPsi);
68+
ildasmProcess.WaitForExit();
69+
Assert.Equal(0, ildasmProcess.ExitCode);
70+
71+
string disasmIl = File.ReadAllText(disasmIlFileName);
72+
73+
// Verify that NaN values use the normalized format without platform-specific suffixes
74+
// The hex representation should be followed by "// -nan" without "(ind)" suffix
75+
var nanFloat64Regex = new Regex(@"float64\(0xFFF8000000000000\)\s+//\s+-nan\s", RegexOptions.Compiled);
76+
Assert.True(nanFloat64Regex.IsMatch(disasmIl),
77+
"NaN float64 should be output as '// -nan' without platform-specific suffixes like '(ind)'");
78+
79+
// Verify the output does NOT contain the Windows-specific "(ind)" suffix
80+
Assert.DoesNotContain("-nan(ind)", disasmIl);
81+
Assert.DoesNotContain("-nan(", disasmIl);
82+
}
83+
84+
private static void GetIlasmProcessStartInfos(
85+
string ilasmFile,
86+
string ildasmFile,
87+
string ilFileName,
88+
out string disasmIlFileName,
89+
out ProcessStartInfo ilasmPsi,
90+
out ProcessStartInfo ildasmPsi)
91+
{
92+
if (!File.Exists(ilFileName))
93+
{
94+
throw new FileNotFoundException(
95+
$"Did not find '{ilFileName}' in working directory '{Environment.CurrentDirectory}'");
96+
}
97+
98+
string currentDirectory = Environment.CurrentDirectory;
99+
100+
ilasmPsi = new ProcessStartInfo();
101+
ilasmPsi.UseShellExecute = false;
102+
ilasmPsi.WorkingDirectory = currentDirectory;
103+
ilasmPsi.FileName = ilasmFile;
104+
string asmDllFileName = $"{Path.GetFileNameWithoutExtension(ilFileName)}.dll";
105+
ilasmPsi.Arguments =
106+
$"-nologo -dll -optimize -output={asmDllFileName} {ilFileName}";
107+
108+
ildasmPsi = new ProcessStartInfo();
109+
ildasmPsi.UseShellExecute = false;
110+
ildasmPsi.WorkingDirectory = currentDirectory;
111+
ildasmPsi.FileName = ildasmFile;
112+
disasmIlFileName = $"{Path.GetFileNameWithoutExtension(ilFileName)}_dis{Path.GetExtension(ilFileName)}";
113+
ildasmPsi.Arguments = $"-out={disasmIlFileName} {asmDllFileName}";
114+
}
115+
116+
public void Dispose() {}
117+
}

src/tests/ilasm/ilasm_tests.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<Compile Include="PortablePdb\IlasmPortablePdbTesterCommon.cs" />
1414
<Compile Include="PortablePdb\IlasmPortablePdbTesterTypes.cs" />
1515
<Compile Include="MethodImplOptions\MethodImplOptionsTests.cs" />
16+
<Compile Include="FloatSpecialValues\FloatSpecialValuesTests.cs" />
1617
</ItemGroup>
1718
<ItemGroup>
1819
<Compile Remove="PortablePdb\Resources\**" />
@@ -68,6 +69,10 @@
6869
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
6970
<Link>%(Filename).il</Link>
7071
</None>
72+
<None Include="FloatSpecialValues/*.il">
73+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
74+
<Link>%(Filename).il</Link>
75+
</None>
7176
</ItemGroup>
7277
<Import Project="$(TestSourceDir)MergedTestRunner.targets" />
7378
</Project>

0 commit comments

Comments
 (0)