[libcxx-commits] [libcxx] 62450ba - [libc++] Improve handling of runtime errors inside SPEC benchmarks

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Sep 25 10:13:49 PDT 2025


Author: Louis Dionne
Date: 2025-09-25T13:13:32-04:00
New Revision: 62450ba905fecc0821f3a08db81f756c8b1f7b7c

URL: https://github.com/llvm/llvm-project/commit/62450ba905fecc0821f3a08db81f756c8b1f7b7c
DIFF: https://github.com/llvm/llvm-project/commit/62450ba905fecc0821f3a08db81f756c8b1f7b7c.diff

LOG: [libc++] Improve handling of runtime errors inside SPEC benchmarks

Previously, we would report a successful run if the benchmark exited
with an error, and we would produce a timing for the benchmark. After
this patch, we consider an error in the benchmark to be a failed LIT
test and we don't produce any benchmark data for it.

Added: 
    

Modified: 
    libcxx/test/benchmarks/spec.gen.py
    libcxx/utils/parse-spec-results

Removed: 
    


################################################################################
diff  --git a/libcxx/test/benchmarks/spec.gen.py b/libcxx/test/benchmarks/spec.gen.py
index 94865ead1f440..c36dd0a3faba2 100644
--- a/libcxx/test/benchmarks/spec.gen.py
+++ b/libcxx/test/benchmarks/spec.gen.py
@@ -72,7 +72,12 @@
     print(f'RUN: %{{spec_dir}}/bin/runcpu --config %T/spec-config.cfg --size train --output-root %T --rebuild {benchmark}')
     print(f'RUN: rm -rf %T/benchspec') # remove the temporary directory, which can become quite large
 
-    # Parse the results into a LNT-compatible format. This also errors out if there are no CSV files, which
-    # means that the benchmark didn't run properly (the `runcpu` command above never reports a failure).
-    print(f'RUN: %{{libcxx-dir}}/utils/parse-spec-results %T/result/*.train.csv --output-format=lnt > %T/results.lnt || ! cat %T/result/*.log')
+    # The `runcpu` command above doesn't fail even if the benchmark fails to run. To determine failure, parse the CSV
+    # results and ensure there are no compilation errors or runtime errors in the status row. Also print the logs and
+    # fail if there are no CSV files at all, which implies a SPEC error.
+    print(f'RUN: %{{libcxx-dir}}/utils/parse-spec-results --extract "Base Status" --keep-failed %T/result/*.train.csv > %T/status || ! cat %T/result/*.log')
+    print(f'RUN: ! grep -E "CE|RE" %T/status || ! cat %T/result/*.log')
+
+    # If there were no errors, parse the results into LNT-compatible format and print them.
+    print(f'RUN: %{{libcxx-dir}}/utils/parse-spec-results %T/result/*.train.csv --output-format=lnt > %T/results.lnt')
     print(f'RUN: cat %T/results.lnt')

diff  --git a/libcxx/utils/parse-spec-results b/libcxx/utils/parse-spec-results
index 3aff206f8959c..2c3c279622ad5 100755
--- a/libcxx/utils/parse-spec-results
+++ b/libcxx/utils/parse-spec-results
@@ -58,7 +58,10 @@ def main(argv):
              'sure to use appropriate quoting for header names that contain spaces. This option only makes sense '
              'when the output format is CSV.')
     parser.add_argument('--keep-not-run', action='store_true',
-        help='Keep entries whose \'Base Status\' is marked as \'NR\', aka \'Not Run\'. By default, such entries are discarded.')
+        help='Keep entries whose "Base Status" is marked as "NR" (aka "Not Run"). By default, such entries are discarded.')
+    parser.add_argument('--keep-failed', action='store_true',
+        help='Keep entries whose "Base Status" is marked as "CE" (aka "Compilation Error") or "RE" (aka "Runtime Error"). '
+             'By default, such entries are discarded.')
     args = parser.parse_args(argv)
 
     if args.table == 'full':
@@ -76,10 +79,12 @@ def main(argv):
         headers = parsed_headers
         rows.extend(parsed_rows)
 
-    # Remove rows that were not run unless we were asked to keep them
+    # Remove rows that were not run (or failed) unless we were asked to keep them
+    status = headers.index('Base Status')
     if not args.keep_not_run:
-        not_run = headers.index('Base Status')
-        rows = [row for row in rows if row[not_run] != 'NR']
+        rows = [row for row in rows if row[status] != 'NR']
+    if not args.keep_failed:
+        rows = [row for row in rows if row[status] not in ('CE', 'RE')]
 
     if args.extract is not None:
         if args.output_format != 'csv':


        


More information about the libcxx-commits mailing list