From 93f30395e869c8af4ff5b92b4a457345789205ca Mon Sep 17 00:00:00 2001 From: Erica Vella Date: Fri, 10 Jul 2026 10:29:34 -0700 Subject: [PATCH] Fix SPEC CPU win-arm64 build failure caused by invalid -march=armv8-a On Windows the SPEC CPU 2017 toolchain is always the x86_64 Cygwin GCC (there is no Arm64 Cygwin distribution), so it runs under x64 emulation on win-arm64 and targets x86_64. The PERF-SPECCPU-*.json profiles computed the optimizing flags purely from CPU architecture: -march={calculate("{Architecture}" == "x64" ? "native" : "armv8-a")} On win-arm64 this produced -march=armv8-a, which the x86_64 Cygwin gcc/gfortran reject: cc1: error: bad value 'armv8-a' for '-march=' switch f951: Error: bad value 'armv8-a' for '-march=' switch Every benchmark's `specmake build` therefore failed (exit 2), but runspeccpu.bat still returned exit 0, so SpecCpuExecutor emitted zero metrics and the QoS goals surfaced as "metrics missing" instead of a build error. Fix: on any Windows platform (Cygwin => x86_64), resolve -march to native. Only linux-arm64 continues to use armv8-a. Validated on a real win-arm64 (Cobalt 100) VM: reproduced the exact make.out compiler error with the x86_64 Cygwin gcc 14.4.0, confirmed -march=native compiles successfully, and added a ProfileExpressionEvaluator regression test covering win-arm64, win-x64, linux-x64 and linux-arm64. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ProfileExpressionEvaluatorTests.cs | 22 +++++++++++++++++++ .../profiles/PERF-SPECCPU-FPRATE.json | 4 ++-- .../profiles/PERF-SPECCPU-FPSPEED.json | 4 ++-- .../profiles/PERF-SPECCPU-INTRATE.json | 4 ++-- .../profiles/PERF-SPECCPU-INTSPEED.json | 4 ++-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Core.UnitTests/ProfileExpressionEvaluatorTests.cs b/src/VirtualClient/VirtualClient.Core.UnitTests/ProfileExpressionEvaluatorTests.cs index 30c2f4a535..d1df807424 100644 --- a/src/VirtualClient/VirtualClient.Core.UnitTests/ProfileExpressionEvaluatorTests.cs +++ b/src/VirtualClient/VirtualClient.Core.UnitTests/ProfileExpressionEvaluatorTests.cs @@ -1714,6 +1714,28 @@ public async Task ProfileExpressionEvaluatorSupportsNestedTernaryFunctionReferen Assert.AreEqual(expectedValue, parameters["Flags"]); } + [Test] + // On Windows the SPECcpu toolchain is always the x86_64 Cygwin GCC (there is no Arm64 Cygwin), so + // '-march=armv8-a' is invalid and must resolve to 'native' even on win-arm64. Only linux-arm64 uses 'armv8-a'. + [TestCase(PlatformID.Win32NT, Architecture.Arm64, "-g -O3 -march=native -frecord-gcc-switches")] + [TestCase(PlatformID.Win32NT, Architecture.X64, "-g -O3 -march=native -frecord-gcc-switches")] + [TestCase(PlatformID.Unix, Architecture.X64, "-g -O3 -march=native -frecord-gcc-switches")] + [TestCase(PlatformID.Unix, Architecture.Arm64, "-g -O3 -march=armv8-a -frecord-gcc-switches")] + public async Task ProfileExpressionEvaluatorResolvesSpecCpuOptimizingFlagsForEachPlatform(PlatformID platform, Architecture architecture, string expectedValue) + { + this.SetupDefaults(platform, architecture); + Dictionary parameters = new Dictionary + { + { + "BaseOptimizingFlags", + "-g -O3 -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -frecord-gcc-switches" + } + }; + + await ProfileExpressionEvaluator.Instance.EvaluateAsync(this.mockFixture.Dependencies, parameters); + Assert.AreEqual(expectedValue, parameters["BaseOptimizingFlags"]); + } + [Test] public async Task ProfileExpressionEvaluatorSupportsPathBasedFunctionAndComparisonOperations_Scenario_1() { diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPRATE.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPRATE.json index 9ff9b81cf5..54aec9fd27 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPRATE.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPRATE.json @@ -19,8 +19,8 @@ "RunPeak": false, "Threads": "{LogicalCoreCount}", "Copies": "{LogicalCoreCount}", - "BaseOptimizingFlags": "-g -O3 -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", - "PeakOptimizingFlags": "-g -Ofast -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" + "BaseOptimizingFlags": "-g -O3 -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", + "PeakOptimizingFlags": "-g -Ofast -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" }, "Actions": [ { diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPSPEED.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPSPEED.json index 9a8de1eee1..7620a07ba0 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPSPEED.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-FPSPEED.json @@ -19,8 +19,8 @@ "RunPeak": false, "Threads": "{LogicalCoreCount}", "Copies": "{LogicalCoreCount}", - "BaseOptimizingFlags": "-g -O3 -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", - "PeakOptimizingFlags": "-g -Ofast -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" + "BaseOptimizingFlags": "-g -O3 -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", + "PeakOptimizingFlags": "-g -Ofast -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" }, "Actions": [ { diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTRATE.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTRATE.json index 8c809a07ab..844f93d5db 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTRATE.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTRATE.json @@ -19,8 +19,8 @@ "RunPeak": false, "Threads": "{LogicalCoreCount}", "Copies": "{LogicalCoreCount}", - "BaseOptimizingFlags": "-g -O3 -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", - "PeakOptimizingFlags": "-g -Ofast -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" + "BaseOptimizingFlags": "-g -O3 -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", + "PeakOptimizingFlags": "-g -Ofast -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" }, "Actions": [ { diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTSPEED.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTSPEED.json index 7f15a3e3bb..e2dc3a04d3 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTSPEED.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-SPECCPU-INTSPEED.json @@ -19,8 +19,8 @@ "RunPeak": false, "Threads": "{LogicalCoreCount}", "Copies": "{LogicalCoreCount}", - "BaseOptimizingFlags": "-g -O3 -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", - "PeakOptimizingFlags": "-g -Ofast -march={calculate(\"{Architecture}\" == \"x64\" ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" + "BaseOptimizingFlags": "-g -O3 -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -frecord-gcc-switches", + "PeakOptimizingFlags": "-g -Ofast -march={calculate((\"{Platform}\".StartsWith(\"win\") || \"{Architecture}\" == \"x64\") ? \"native\" : \"armv8-a\")} -flto -frecord-gcc-switches" }, "Actions": [ {