[lld] [lld][COFF] Mirror ELF LTO sample profile collection in reproducers (PR #225026)

Haohai Wen via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 01:31:25 PDT 2026


https://github.com/HaohaiWen created https://github.com/llvm/llvm-project/pull/225026

Mirror ELF's reproducer behavior by archiving the file named by
/lto-sample-profile and rewriting the option's path in the generated
response file. This lets reproduced links load the profile from the archive.

>From 31c1137193a112089043dcec0eb523ea5312778c Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Mon, 21 Sep 2026 14:55:13 +0800
Subject: [PATCH] [lld][COFF] Mirror ELF LTO sample profile collection in
 reproducers

Mirror ELF's reproducer behavior by archiving the file named by
/lto-sample-profile and rewriting the option's path in the generated
response file. This lets reproduced links load the profile from the
archive.
---
 lld/COFF/Driver.cpp          |  9 +++++++++
 lld/test/COFF/linkrepro.test | 14 ++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index ecbb5e9fff4e19..1afc6160a7e8b7 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -954,6 +954,7 @@ static std::string createResponseFile(const opt::InputArgList &args,
     case OPT_INPUT:
       os << quote(rewritePath(arg->getValue())) << "\n";
       break;
+    case OPT_lto_sample_profile:
     case OPT_wholearchive_file:
       os << arg->getSpelling() << quote(rewritePath(arg->getValue())) << "\n";
       break;
@@ -1710,6 +1711,14 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
                  << toString(errOrWriter.takeError());
       }
     }
+
+    // LTO reads the sample profile directly, so collect it explicitly.
+    if (tar) {
+      StringRef ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
+      if (!ltoSampleProfile.empty())
+        takeBuffer(CHECK(MemoryBuffer::getFile(ltoSampleProfile),
+                         "could not open " + ltoSampleProfile));
+    }
   }
   // Handle /linkreprofullpathrsp
   if (auto *arg = args.getLastArg(OPT_linkreprofullpathrsp)) {
diff --git a/lld/test/COFF/linkrepro.test b/lld/test/COFF/linkrepro.test
index b1195cccb0e8a7..ad311aa05c59e1 100644
--- a/lld/test/COFF/linkrepro.test
+++ b/lld/test/COFF/linkrepro.test
@@ -10,6 +10,7 @@
 # RUN: echo '_main at 0' > %t.order
 # RUN: touch %t.def
 # RUN: touch %t.cg
+# RUN: touch %t.prof
 
 Test link.exe-style /linkrepro: flag.
 # RUN: mkdir -p %t.dir/build1
@@ -181,6 +182,19 @@ Test /start-lib / /end-lib with /linkrepro:
 # RSP-STARTLIB-NEXT: /end-lib
 # RSP-STARTLIB: /out:
 
+Test /lto-sample-profile: with /linkrepro:
+# RUN: mkdir -p %t.dir/build9
+# RUN: cd %t.dir/build9
+# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
+# RUN:   /entry:main at 0 /linkrepro:. /out:%t.exe \
+# RUN:   /lto-sample-profile:%t.prof
+# RUN: tar xf repro.tar
+# RUN: diff %t.prof repro/%:t.prof
+# RUN: FileCheck %s --check-prefix=RSP-LTO < repro/response.txt
+# RUN: cd repro; lld-link @response.txt
+
+# RSP-LTO: {{^/lto-sample-profile:[^/].*linkrepro\.test\.tmp\.prof$}}
+
 #--- drectve.s
         .section .drectve, "yn"
         .ascii "/defaultlib:std32"



More information about the llvm-commits mailing list