diff --git a/src/coreclr/ildasm/dasm.cpp b/src/coreclr/ildasm/dasm.cpp
index 45f0070ffc390d..d83c1822db472a 100644
--- a/src/coreclr/ildasm/dasm.cpp
+++ b/src/coreclr/ildasm/dasm.cpp
@@ -2593,6 +2593,7 @@ void DumpDefaultValue(mdToken tok, __inout __nullterminated char* szString, void
char szf[32];
sprintf_s(szf, 32, "%#.8g", (double)MDDV.m_fltValue);
float df = (float)atof(szf);
+ NormalizeFloatString(szf);
// Must compare as underlying bytes, not floating point otherwise optimizer will
// try to enregister and compare 80-bit precision number with 32-bit precision number!!!!
if((*(ULONG*)&df == MDDV.m_ulValue)&&!IsSpecialNumber(szf))
@@ -2608,6 +2609,7 @@ void DumpDefaultValue(mdToken tok, __inout __nullterminated char* szString, void
sprintf_s(szf, 32, "%#.17g", MDDV.m_dblValue);
double df = strtod(szf, &pch); //atof(szf);
szf[31]=0;
+ NormalizeFloatString(szf);
// Must compare as underlying bytes, not floating point otherwise optimizer will
// try to enregister and compare 80-bit precision number with 64-bit precision number!!!!
if((*(ULONGLONG*)&df == MDDV.m_ullValue)&&!IsSpecialNumber(szf))
diff --git a/src/coreclr/ildasm/dis.cpp b/src/coreclr/ildasm/dis.cpp
index 8a70fc714433c2..5b784e4f9424cf 100644
--- a/src/coreclr/ildasm/dis.cpp
+++ b/src/coreclr/ildasm/dis.cpp
@@ -2767,3 +2767,25 @@ bool IsSpecialNumber(const char* szf)
|| (strstr(szf, "nan") != NULL) || (strstr(szf, "NAN") != NULL)
|| (strstr(szf, "inf") != NULL) || (strstr(szf, "INF") != NULL);
}
+
+void NormalizeFloatString(char* szf)
+{
+ // Normalize NaN representations to remove platform-specific suffixes
+ // Windows can produce "-nan(ind)" while Linux produces "-nan"
+ // This function removes the "(ind)" suffix to ensure cross-platform consistency
+
+ char* nan_pos = strstr(szf, "nan(");
+ if (nan_pos != NULL)
+ {
+ // "nan" is 3 characters, so truncate at position 3 from the match
+ nan_pos[3] = '\0';
+ }
+
+ // Also handle uppercase NAN
+ char* NAN_pos = strstr(szf, "NAN(");
+ if (NAN_pos != NULL)
+ {
+ // "NAN" is 3 characters, so truncate at position 3 from the match
+ NAN_pos[3] = '\0';
+ }
+}
diff --git a/src/coreclr/ildasm/dis.h b/src/coreclr/ildasm/dis.h
index 1b60192a60b82e..1f75e5f8cd7434 100644
--- a/src/coreclr/ildasm/dis.h
+++ b/src/coreclr/ildasm/dis.h
@@ -83,6 +83,7 @@ char* DumpUnicodeString(void* GUICookie,
void TokenSigInit(IMDInternalImport *pImport);
void TokenSigDelete();
bool IsSpecialNumber(const char*);
+void NormalizeFloatString(char*);
//---------------- see DMAN.CPP--------------------------------------------------
diff --git a/src/tests/ilasm/FloatSpecialValues/FloatSpecialValues.il b/src/tests/ilasm/FloatSpecialValues/FloatSpecialValues.il
new file mode 100644
index 00000000000000..1cc689c0716b3a
--- /dev/null
+++ b/src/tests/ilasm/FloatSpecialValues/FloatSpecialValues.il
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+.assembly extern System.Runtime { }
+.assembly FloatSpecialValues { }
+
+.class public auto ansi beforefieldinit TestFloatSpecialValues
+ extends [System.Runtime]System.Object
+{
+ // Test NaN values - these should output with normalized "// -nan" comment
+ .field public static literal float64 NaNValue = float64(0xFFF8000000000000)
+
+ // Test infinity values for completeness
+ .field public static literal float64 PositiveInf = float64(0x7FF0000000000000)
+ .field public static literal float64 NegativeInf = float64(0xFFF0000000000000)
+
+ // Test float32 NaN as well
+ .field public static literal float32 NaNValue32 = float32(0xFFC00000)
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ .maxstack 8
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ret
+ }
+}
diff --git a/src/tests/ilasm/FloatSpecialValues/FloatSpecialValuesTests.cs b/src/tests/ilasm/FloatSpecialValues/FloatSpecialValuesTests.cs
new file mode 100644
index 00000000000000..c57f50528f5cbc
--- /dev/null
+++ b/src/tests/ilasm/FloatSpecialValues/FloatSpecialValuesTests.cs
@@ -0,0 +1,117 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Text.RegularExpressions;
+using Xunit;
+
+public class FloatSpecialValuesTests : IDisposable
+{
+ private string _ilasmFile;
+ private string _ildasmFile;
+
+ public FloatSpecialValuesTests()
+ {
+ string coreRoot = Environment.GetEnvironmentVariable("CORE_ROOT");
+ if (string.IsNullOrWhiteSpace(coreRoot))
+ {
+ Console.WriteLine("Environment variable is not set: 'CORE_ROOT'");
+ throw new InvalidOperationException("Environment variable is not set: 'CORE_ROOT'");
+ }
+ if (!Directory.Exists(coreRoot))
+ {
+ Console.WriteLine($"Did not find CORE_ROOT directory: {coreRoot}");
+ throw new InvalidOperationException("Did not find CORE_ROOT directory");
+ }
+
+ var nativeExeExtensions = new string[] { string.Empty, ".exe" };
+ bool found = false;
+ string ilasmFile = null;
+ string ildasmFile = null;
+ foreach (string nativeExeExtension in nativeExeExtensions)
+ {
+ ilasmFile = Path.Combine(coreRoot, $"ilasm{nativeExeExtension}");
+ ildasmFile = Path.Combine(coreRoot, $"ildasm{nativeExeExtension}");
+ if (File.Exists(ilasmFile) && File.Exists(ildasmFile))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ Console.WriteLine($"Did not find ilasm or ildasm in CORE_ROOT directory: {coreRoot}");
+ throw new InvalidOperationException("Did not find ilasm or ildasm in CORE_ROOT directory");
+ }
+
+ _ilasmFile = ilasmFile;
+ _ildasmFile = ildasmFile;
+ }
+
+ [Fact]
+ public void NaNOutputIsNormalizedAcrossPlatforms()
+ {
+ Console.WriteLine("NaNOutputIsNormalizedAcrossPlatforms");
+
+ string ilFileName = "FloatSpecialValues.il";
+ string disasmIlFileName;
+ ProcessStartInfo ilasmPsi, ildasmPsi;
+ GetIlasmProcessStartInfos(_ilasmFile, _ildasmFile, ilFileName, out disasmIlFileName, out ilasmPsi, out ildasmPsi);
+
+ Process ilasmProcess = Process.Start(ilasmPsi);
+ ilasmProcess.WaitForExit();
+ Assert.Equal(0, ilasmProcess.ExitCode);
+
+ Process ildasmProcess = Process.Start(ildasmPsi);
+ ildasmProcess.WaitForExit();
+ Assert.Equal(0, ildasmProcess.ExitCode);
+
+ string disasmIl = File.ReadAllText(disasmIlFileName);
+
+ // Verify that NaN values use the normalized format without platform-specific suffixes
+ // The hex representation should be followed by "// -nan" without "(ind)" suffix
+ var nanFloat64Regex = new Regex(@"float64\(0xFFF8000000000000\)\s+//\s+-nan\s", RegexOptions.Compiled);
+ Assert.True(nanFloat64Regex.IsMatch(disasmIl),
+ "NaN float64 should be output as '// -nan' without platform-specific suffixes like '(ind)'");
+
+ // Verify the output does NOT contain the Windows-specific "(ind)" suffix
+ Assert.DoesNotContain("-nan(ind)", disasmIl);
+ Assert.DoesNotContain("-nan(", disasmIl);
+ }
+
+ private static void GetIlasmProcessStartInfos(
+ string ilasmFile,
+ string ildasmFile,
+ string ilFileName,
+ out string disasmIlFileName,
+ out ProcessStartInfo ilasmPsi,
+ out ProcessStartInfo ildasmPsi)
+ {
+ if (!File.Exists(ilFileName))
+ {
+ throw new FileNotFoundException(
+ $"Did not find '{ilFileName}' in working directory '{Environment.CurrentDirectory}'");
+ }
+
+ string currentDirectory = Environment.CurrentDirectory;
+
+ ilasmPsi = new ProcessStartInfo();
+ ilasmPsi.UseShellExecute = false;
+ ilasmPsi.WorkingDirectory = currentDirectory;
+ ilasmPsi.FileName = ilasmFile;
+ string asmDllFileName = $"{Path.GetFileNameWithoutExtension(ilFileName)}.dll";
+ ilasmPsi.Arguments =
+ $"-nologo -dll -optimize -output={asmDllFileName} {ilFileName}";
+
+ ildasmPsi = new ProcessStartInfo();
+ ildasmPsi.UseShellExecute = false;
+ ildasmPsi.WorkingDirectory = currentDirectory;
+ ildasmPsi.FileName = ildasmFile;
+ disasmIlFileName = $"{Path.GetFileNameWithoutExtension(ilFileName)}_dis{Path.GetExtension(ilFileName)}";
+ ildasmPsi.Arguments = $"-out={disasmIlFileName} {asmDllFileName}";
+ }
+
+ public void Dispose() {}
+}
diff --git a/src/tests/ilasm/ilasm_tests.csproj b/src/tests/ilasm/ilasm_tests.csproj
index 6e4d9a17c241af..b08c49dd105509 100644
--- a/src/tests/ilasm/ilasm_tests.csproj
+++ b/src/tests/ilasm/ilasm_tests.csproj
@@ -13,6 +13,7 @@
+
@@ -68,6 +69,10 @@
Always
%(Filename).il
+
+ Always
+ %(Filename).il
+