https://github.com/jdenny-ornl updated https://github.com/llvm/llvm-project/pull/149003
>From 670d2ab7ad2df476e89326dc1845106453ec7579 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" <jdenny.o...@gmail.com> Date: Tue, 15 Jul 2025 21:10:03 -0400 Subject: [PATCH 1/5] [LinkerWrapper] Fix -fsave-optimization-record default file As discussed in PR #145603, the following command fails to produce a YAML remarks file for offload LTO passes and thus for kernel-info: ``` clang -O2 -g -fopenmp --offload-arch=native test.c -foffload-lto \ -Rpass=kernel-info -fsave-optimization-record ``` The problem is that, in clang-linker-wrapper's clang call, clang names the file based on clang's main output file (from `-o`). That is a temporary file, so the YAML file becomes a temporary file, which the user never sees. This patch: - Extends clang with a hidden `-foutput-file-base=BASE` option that overrides the main output file as the base for other output files. - Makes clang honor that option only for the default YAML remarks file, but future patches could use it for other output files too. - Extends clang-linker-wrapper to specify that option to clang. --- clang/include/clang/Driver/Options.td | 6 ++++ .../include/clang/Frontend/FrontendOptions.h | 3 ++ clang/lib/Driver/ToolChains/CommonArgs.cpp | 8 +++-- clang/test/Driver/linker-wrapper.c | 32 +++++++++---------- clang/test/Driver/opt-record.c | 11 +++++++ .../ClangLinkerWrapper.cpp | 11 ++++--- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0b54a446309b..d96e1437f0f40 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5880,6 +5880,12 @@ def o : JoinedOrSeparate<["-"], "o">, Visibility<[ClangOption, CC1Option, CC1AsOption, FC1Option, FlangOption]>, HelpText<"Write output to <file>">, MetaVarName<"<file>">, MarshallingInfoString<FrontendOpts<"OutputFile">>; +def foutput_file_base : Joined<["-"], "foutput-file-base=">, + Flags<[NoXarchOption, HelpHidden]>, + Visibility<[ClangOption]>, + HelpText<"Name extra output files after <base> not the main output file">, + MetaVarName<"<base>">, + MarshallingInfoString<FrontendOpts<"OutputFileBase">>; def object_file_name_EQ : Joined<["-"], "object-file-name=">, Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>, HelpText<"Set the output <file> for debug infos">, MetaVarName<"<file>">, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index c919a53ae089e..a03165e05962c 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -439,6 +439,9 @@ class FrontendOptions { /// The output file, if any. std::string OutputFile; + /// The base, if any, to use instead of OutputFile for extra output files. + std::string OutputFileBase; + /// If given, the new suffix for fix-it rewritten files. std::string FixItSuffix; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 097d186ad8ea4..513425a855511 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -294,8 +294,9 @@ static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, Format = A->getValue(); SmallString<128> F; - const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ); - if (A) + if (const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ)) + F = A->getValue(); + else if (const Arg *A = Args.getLastArg(options::OPT_foutput_file_base)) F = A->getValue(); else if (Output.isFilename()) F = Output.getFilename(); @@ -1320,6 +1321,9 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, if (Args.hasArg(options::OPT_ftime_report)) CmdArgs.push_back( Args.MakeArgString(Twine(PluginOptPrefix) + "-time-passes")); + + // clang-linker-wrapper adds this without checking if it is needed. + Args.ClaimAllArgs(options::OPT_foutput_file_base); } void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC, diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c index 80b1a5745a123..d97328b6600a8 100644 --- a/clang/test/Driver/linker-wrapper.c +++ b/clang/test/Driver/linker-wrapper.c @@ -22,7 +22,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=NVPTX-LINK -// NVPTX-LINK: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o +// NVPTX-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.nvptx64.sm_70.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \ @@ -40,7 +40,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=AMDGPU-LINK -// AMDGPU-LINK: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// AMDGPU-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx1030 \ @@ -57,7 +57,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: not clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=SPIRV-LINK -// SPIRV-LINK: clang{{.*}} -o {{.*}}.img --target=spirv64-unknown-unknown {{.*}}.o --sycl-link -Xlinker -triple=spirv64-unknown-unknown -Xlinker -arch= +// SPIRV-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.spirv64..img --target=spirv64-unknown-unknown {{.*}}.o --sycl-link -Xlinker -triple=spirv64-unknown-unknown -Xlinker -arch= // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \ @@ -68,7 +68,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld --whole-archive %t.a --no-whole-archive \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CPU-LINK -// CPU-LINK: clang{{.*}} -o {{.*}}.img --target=x86_64-unknown-linux-gnu -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared -Wl,--whole-archive {{.*}}.a -Wl,--no-whole-archive +// CPU-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.x86_64..img --target=x86_64-unknown-linux-gnu -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared -Wl,--whole-archive {{.*}}.a -Wl,--no-whole-archive // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -mllvm -openmp-opt-disable \ @@ -100,8 +100,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CUDA -// CUDA: clang{{.*}} -o [[IMG_SM70:.+]] --target=nvptx64-nvidia-cuda -march=sm_70 -// CUDA: clang{{.*}} -o [[IMG_SM52:.+]] --target=nvptx64-nvidia-cuda -march=sm_52 +// CUDA: clang{{.*}} -o [[IMG_SM70:.+]] -foutput-file-base=a.out.nvptx64.sm_70.img --target=nvptx64-nvidia-cuda -march=sm_70 +// CUDA: clang{{.*}} -o [[IMG_SM52:.+]] -foutput-file-base=a.out.nvptx64.sm_52.img --target=nvptx64-nvidia-cuda -march=sm_52 // CUDA: fatbinary{{.*}}-64 --create {{.*}}.fatbin --image=profile=sm_70,file=[[IMG_SM70]] --image=profile=sm_52,file=[[IMG_SM52]] // CUDA: usr/bin/ld{{.*}} {{.*}}.openmp.image.{{.*}}.o {{.*}}.cuda.image.{{.*}}.o @@ -127,8 +127,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --compress --compression-level=6 \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP -// HIP: clang{{.*}} -o [[IMG_GFX90A:.+]] --target=amdgcn-amd-amdhsa -mcpu=gfx90a -// HIP: clang{{.*}} -o [[IMG_GFX908:.+]] --target=amdgcn-amd-amdhsa -mcpu=gfx908 +// HIP: clang{{.*}} -o [[IMG_GFX90A:.+]] -foutput-file-base=a.out.amdgcn.gfx90a.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a +// HIP: clang{{.*}} -o [[IMG_GFX908:.+]] -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 // HIP: clang-offload-bundler{{.*}}-type=o -bundle-align=4096 -compress -compression-level=6 -targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa--gfx90a,hip-amdgcn-amd-amdhsa--gfx908 -input={{/dev/null|NUL}} -input=[[IMG_GFX90A]] -input=[[IMG_GFX908]] -output={{.*}}.hipfb // RUN: clang-offload-packager -o %t.out \ @@ -157,7 +157,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --clang-backend \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CLANG-BACKEND -// CLANG-BACKEND: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o +// CLANG-BACKEND: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 @@ -180,8 +180,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t-on.o %t-off.o %t.a -o a.out 2>&1 | FileCheck %s --check-prefix=AMD-TARGET-ID -// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+ -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o -// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack- -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a:xnack+.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+ -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a:xnack-.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack- -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t-lib.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=generic @@ -196,8 +196,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t1.o %t2.o %t.a -o a.out 2>&1 | FileCheck %s --check-prefix=ARCH-ALL -// ARCH-ALL: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o -// ARCH-ALL: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// ARCH-ALL: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// ARCH-ALL: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \ @@ -207,7 +207,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld -r %t.o \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=RELOCATABLE-LINK -// RELOCATABLE-LINK: clang{{.*}} -o {{.*}}.img --target=x86_64-unknown-linux-gnu +// RELOCATABLE-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.x86_64..img --target=x86_64-unknown-linux-gnu // RELOCATABLE-LINK: /usr/bin/ld.lld{{.*}}-r // RELOCATABLE-LINK: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading @@ -219,7 +219,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld -r %t.o \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=RELOCATABLE-LINK-HIP -// RELOCATABLE-LINK-HIP: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa +// RELOCATABLE-LINK-HIP: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a.img --target=amdgcn-amd-amdhsa // RELOCATABLE-LINK-HIP: clang-offload-bundler{{.*}} -type=o -bundle-align=4096 -targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa--gfx90a -input={{/dev/null|NUL}} -input={{.*}} -output={{.*}} // RELOCATABLE-LINK-HIP: /usr/bin/ld.lld{{.*}}-r // RELOCATABLE-LINK-HIP: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading @@ -233,7 +233,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld -r %t.o \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=RELOCATABLE-LINK-CUDA -// RELOCATABLE-LINK-CUDA: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda +// RELOCATABLE-LINK-CUDA: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.nvptx64.sm_89.img --target=nvptx64-nvidia-cuda // RELOCATABLE-LINK-CUDA: fatbinary{{.*}} -64 --create {{.*}}.fatbin --image=profile=sm_89,file={{.*}}.img // RELOCATABLE-LINK-CUDA: /usr/bin/ld.lld{{.*}}-r // RELOCATABLE-LINK-CUDA: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading diff --git a/clang/test/Driver/opt-record.c b/clang/test/Driver/opt-record.c index 220f5db7fbca2..afbc2a012abb1 100644 --- a/clang/test/Driver/opt-record.c +++ b/clang/test/Driver/opt-record.c @@ -78,3 +78,14 @@ // CHECK-PASS-RPASS-SAME: "-plugin-opt=opt-remarks-hotness-threshold=100" // CHECK-PASS-AUTO: "-plugin-opt=opt-remarks-hotness-threshold=auto" + +// Check -foutput-file-base effect on -foptimization-record-file. +// RUN: %clang --target=x86_64-linux -### -fuse-ld=lld -B%S/Inputs/lld -flto -fsave-optimization-record -foutput-file-base=/dir/file.ext %s 2>&1 | FileCheck %s -check-prefix=CHECK-BASE +// RUN: %clang --target=x86_64-linux -### -o FOO -fuse-ld=lld -B%S/Inputs/lld -flto -fsave-optimization-record -foutput-file-base=/dir/file.ext %s 2>&1 | FileCheck %s -check-prefix=CHECK-BASE +// RUN: %clang --target=x86_64-linux -### -fuse-ld=lld -B%S/Inputs/lld -flto -fsave-optimization-record -foptimization-record-file=user-file.ext -foutput-file-base=/dir/file.ext %s 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-BASE + +// CHECK-BASE: "-plugin-opt=opt-remarks-filename=/dir/file.ext.opt.ld.yaml" +// CHECK-BASE-SAME: "-plugin-opt=opt-remarks-format=yaml" + +// CHECK-IGNORE-BASE: "-plugin-opt=opt-remarks-filename=user-file.ext.opt.ld.yaml" +// CHECK-IGNORE-BASE-SAME: "-plugin-opt=opt-remarks-format=yaml" diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 9d34b62da20f5..8a459efc843b4 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/TargetID.h" #include "clang/Basic/Version.h" +#include "clang/Driver/Options.h" #include "llvm/ADT/MapVector.h" #include "llvm/BinaryFormat/Magic.h" #include "llvm/Bitcode/BitcodeWriter.h" @@ -474,10 +475,10 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args, StringRef Arch = Args.getLastArgValue(OPT_arch_EQ); // Create a new file to write the linked device image to. Assume that the // input filename already has the device and architecture. - auto TempFileOrErr = - createOutputFile(sys::path::filename(ExecutableName) + "." + - Triple.getArchName() + "." + Arch, - "img"); + std::string OutputFileBase = + "." + Triple.getArchName().str() + "." + Arch.str(); + auto TempFileOrErr = createOutputFile( + sys::path::filename(ExecutableName) + OutputFileBase, "img"); if (!TempFileOrErr) return TempFileOrErr.takeError(); @@ -486,6 +487,8 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args, "--no-default-config", "-o", *TempFileOrErr, + Args.MakeArgString("-foutput-file-base=" + ExecutableName + + OutputFileBase + ".img"), Args.MakeArgString("--target=" + Triple.getTriple()), }; >From ed6071d5dd69ea0d01aef0d74c8c2fea1cd02829 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" <jdenny.o...@gmail.com> Date: Wed, 16 Jul 2025 15:59:33 -0400 Subject: [PATCH 2/5] Drop unused OutputFileBase variable --- clang/include/clang/Driver/Options.td | 3 +-- clang/include/clang/Frontend/FrontendOptions.h | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 6e20466e35966..58ec37e327940 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5899,8 +5899,7 @@ def foutput_file_base : Joined<["-"], "foutput-file-base=">, Flags<[NoXarchOption, HelpHidden]>, Visibility<[ClangOption]>, HelpText<"Name extra output files after <base> not the main output file">, - MetaVarName<"<base>">, - MarshallingInfoString<FrontendOpts<"OutputFileBase">>; + MetaVarName<"<base>">; def object_file_name_EQ : Joined<["-"], "object-file-name=">, Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>, HelpText<"Set the output <file> for debug infos">, MetaVarName<"<file>">, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index a03165e05962c..c919a53ae089e 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -439,9 +439,6 @@ class FrontendOptions { /// The output file, if any. std::string OutputFile; - /// The base, if any, to use instead of OutputFile for extra output files. - std::string OutputFileBase; - /// If given, the new suffix for fix-it rewritten files. std::string FixItSuffix; >From a04b47058378274a046d835efe9a4f49ff579d58 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" <jdenny.o...@gmail.com> Date: Wed, 16 Jul 2025 15:59:41 -0400 Subject: [PATCH 3/5] Extend to benefit -gsplit-dwarf as well --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 10 ++++- clang/test/Driver/opt-record.c | 47 +++++++++++++++++----- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 79b00259367d3..80a3bf185dd92 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1068,9 +1068,15 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, } } - if (Args.hasArg(options::OPT_gsplit_dwarf)) + if (Args.hasArg(options::OPT_gsplit_dwarf)) { + StringRef F; + if (const Arg *A = Args.getLastArg(options::OPT_foutput_file_base)) + F = A->getValue(); + else + F = Output.getFilename(); CmdArgs.push_back(Args.MakeArgString( - Twine(PluginOptPrefix) + "dwo_dir=" + Output.getFilename() + "_dwo")); + Twine(PluginOptPrefix) + "dwo_dir=" + F + "_dwo")); + } if (IsThinLTO && !IsOSAIX) CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + "thinlto")); diff --git a/clang/test/Driver/opt-record.c b/clang/test/Driver/opt-record.c index afbc2a012abb1..c648bf80fabeb 100644 --- a/clang/test/Driver/opt-record.c +++ b/clang/test/Driver/opt-record.c @@ -79,13 +79,40 @@ // CHECK-PASS-AUTO: "-plugin-opt=opt-remarks-hotness-threshold=auto" -// Check -foutput-file-base effect on -foptimization-record-file. -// RUN: %clang --target=x86_64-linux -### -fuse-ld=lld -B%S/Inputs/lld -flto -fsave-optimization-record -foutput-file-base=/dir/file.ext %s 2>&1 | FileCheck %s -check-prefix=CHECK-BASE -// RUN: %clang --target=x86_64-linux -### -o FOO -fuse-ld=lld -B%S/Inputs/lld -flto -fsave-optimization-record -foutput-file-base=/dir/file.ext %s 2>&1 | FileCheck %s -check-prefix=CHECK-BASE -// RUN: %clang --target=x86_64-linux -### -fuse-ld=lld -B%S/Inputs/lld -flto -fsave-optimization-record -foptimization-record-file=user-file.ext -foutput-file-base=/dir/file.ext %s 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-BASE - -// CHECK-BASE: "-plugin-opt=opt-remarks-filename=/dir/file.ext.opt.ld.yaml" -// CHECK-BASE-SAME: "-plugin-opt=opt-remarks-format=yaml" - -// CHECK-IGNORE-BASE: "-plugin-opt=opt-remarks-filename=user-file.ext.opt.ld.yaml" -// CHECK-IGNORE-BASE-SAME: "-plugin-opt=opt-remarks-format=yaml" +// Check -foutput-file-base effect on -foptimization-record-file and +// -gsplit-dwarf. +// +// DEFINE: %{RUN-BASE} = \ +// DEFINE: %clang --target=x86_64-linux -### -fuse-ld=lld -B%S/Inputs/lld \ +// DEFINE: -flto -fsave-optimization-record -gsplit-dwarf %s +// +// RUN: %{RUN-BASE} 2>&1 | FileCheck %s -check-prefix=CHECK-BASE-NONE +// +// RUN: %{RUN-BASE} -o FOO 2>&1 | FileCheck %s -check-prefix=CHECK-BASE-O +// +// RUN: %{RUN-BASE} -foutput-file-base=/dir/file.ext 2>&1 | \ +// RUN: FileCheck %s -check-prefix=CHECK-BASE +// +// RUN: %{RUN-BASE} -o FOO -foutput-file-base=/dir/file.ext 2>&1 | \ +// RUN: FileCheck %s -check-prefix=CHECK-BASE +// +// There is currently no option to ignore -foutput-file-base in the case of +// -gsplit-dwarf. +// RUN: %{RUN-BASE} -foutput-file-base=/dir/file.ext \ +// RUN: -foptimization-record-file=user-file.ext 2>&1 | \ +// RUN: FileCheck %s -check-prefix=CHECK-BASE-IGNORE +// +// CHECK-BASE-NONE: "-plugin-opt=dwo_dir=a.out_dwo" +// CHECK-BASE-NONE-SAME: "-plugin-opt=opt-remarks-filename=a.out.opt.ld.yaml" +// CHECK-BASE-NONE-SAME: "-plugin-opt=opt-remarks-format=yaml" +// +// CHECK-BASE-O: "-plugin-opt=dwo_dir=FOO_dwo" +// CHECK-BASE-O-SAME: "-plugin-opt=opt-remarks-filename=FOO.opt.ld.yaml" +// CHECK-BASE-O-SAME: "-plugin-opt=opt-remarks-format=yaml" +// +// CHECK-BASE: "-plugin-opt=dwo_dir=/dir/file.ext_dwo" +// CHECK-BASE-SAME: "-plugin-opt=opt-remarks-filename=/dir/file.ext.opt.ld.yaml" +// CHECK-BASE-SAME: "-plugin-opt=opt-remarks-format=yaml" +// +// CHECK-BASE-IGNORE: "-plugin-opt=opt-remarks-filename=user-file.ext.opt.ld.yaml" +// CHECK-BASE-IGNORE-SAME: "-plugin-opt=opt-remarks-format=yaml" >From 25381a23798a7a8745219542810c20e4e37376a2 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" <jdenny.o...@gmail.com> Date: Wed, 16 Jul 2025 17:23:51 -0400 Subject: [PATCH 4/5] Apply clang-format --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 80a3bf185dd92..e76b3bfee901d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1074,8 +1074,8 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, F = A->getValue(); else F = Output.getFilename(); - CmdArgs.push_back(Args.MakeArgString( - Twine(PluginOptPrefix) + "dwo_dir=" + F + "_dwo")); + CmdArgs.push_back( + Args.MakeArgString(Twine(PluginOptPrefix) + "dwo_dir=" + F + "_dwo")); } if (IsThinLTO && !IsOSAIX) >From 81db69d90cf1372feb4da55127fd21ff9cb2c684 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" <jdenny.o...@gmail.com> Date: Thu, 17 Jul 2025 21:37:05 -0400 Subject: [PATCH 5/5] Drop -foutput-file-base, use -dumpdir --- clang/include/clang/Driver/Options.td | 5 -- clang/lib/Driver/ToolChains/CommonArgs.cpp | 27 ++++++----- clang/test/Driver/linker-wrapper-libs.c | 32 ++++++------- clang/test/Driver/linker-wrapper.c | 32 ++++++------- clang/test/Driver/lto-dwo.c | 20 +++++++- clang/test/Driver/opt-record.c | 46 +++++-------------- .../ClangLinkerWrapper.cpp | 9 ++-- 7 files changed, 82 insertions(+), 89 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 58ec37e327940..a8c1b5dd8ab3b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5895,11 +5895,6 @@ def o : JoinedOrSeparate<["-"], "o">, Visibility<[ClangOption, CC1Option, CC1AsOption, FC1Option, FlangOption]>, HelpText<"Write output to <file>">, MetaVarName<"<file>">, MarshallingInfoString<FrontendOpts<"OutputFile">>; -def foutput_file_base : Joined<["-"], "foutput-file-base=">, - Flags<[NoXarchOption, HelpHidden]>, - Visibility<[ClangOption]>, - HelpText<"Name extra output files after <base> not the main output file">, - MetaVarName<"<base>">; def object_file_name_EQ : Joined<["-"], "object-file-name=">, Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>, HelpText<"Set the output <file> for debug infos">, MetaVarName<"<file>">, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index e76b3bfee901d..4e5d2fbd34e2e 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -294,18 +294,22 @@ static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, Format = A->getValue(); SmallString<128> F; - if (const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ)) + if (const Arg *A = + Args.getLastArg(options::OPT_foptimization_record_file_EQ)) { F = A->getValue(); - else if (const Arg *A = Args.getLastArg(options::OPT_foutput_file_base)) + F += "."; + } else if (const Arg *A = Args.getLastArg(options::OPT_dumpdir)) { F = A->getValue(); - else if (Output.isFilename()) + } else if (Output.isFilename()) { F = Output.getFilename(); + F += "."; + } assert(!F.empty() && "Cannot determine remarks output name."); // Append "opt.ld.<format>" to the end of the file name. CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + - "opt-remarks-filename=" + F + - ".opt.ld." + Format)); + "opt-remarks-filename=" + F + "opt.ld." + + Format)); if (const Arg *A = Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) @@ -1069,13 +1073,15 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, } if (Args.hasArg(options::OPT_gsplit_dwarf)) { - StringRef F; - if (const Arg *A = Args.getLastArg(options::OPT_foutput_file_base)) + SmallString<128> F; + if (const Arg *A = Args.getLastArg(options::OPT_dumpdir)) { F = A->getValue(); - else + } else { F = Output.getFilename(); + F += "_"; + } CmdArgs.push_back( - Args.MakeArgString(Twine(PluginOptPrefix) + "dwo_dir=" + F + "_dwo")); + Args.MakeArgString(Twine(PluginOptPrefix) + "dwo_dir=" + F + "dwo")); } if (IsThinLTO && !IsOSAIX) @@ -1338,9 +1344,6 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, for (auto A : Args.getAllArgValues(options::OPT_Xthinlto_distributor_EQ)) CmdArgs.push_back(Args.MakeArgString("--thinlto-distributor-arg=" + A)); } - - // clang-linker-wrapper adds this without checking if it is needed. - Args.ClaimAllArgs(options::OPT_foutput_file_base); } void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC, diff --git a/clang/test/Driver/linker-wrapper-libs.c b/clang/test/Driver/linker-wrapper-libs.c index cb5c7c137a0ba..1404fe3fc7a3e 100644 --- a/clang/test/Driver/linker-wrapper-libs.c +++ b/clang/test/Driver/linker-wrapper-libs.c @@ -48,8 +48,8 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.a %t.o -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-RESOLVES -// LIBRARY-RESOLVES: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o -// LIBRARY-RESOLVES: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o +// LIBRARY-RESOLVES: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o +// LIBRARY-RESOLVES: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o // // Check that we extract a static library that defines a global visibile to the @@ -72,8 +72,8 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.a %t.o -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-GLOBAL -// LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o -// LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o +// LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o +// LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o // // Check that we do not extract a global symbol if the source file was not @@ -95,8 +95,8 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.o %t.a -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-GLOBAL-NONE -// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o -// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o +// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o +// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o // // Check that we do not extract an external weak symbol. @@ -116,9 +116,9 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.o %t.a -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-WEAK -// LIBRARY-WEAK: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 +// LIBRARY-WEAK: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_70 // LIBRARY-WEAK-NOT: {{.*}}.o {{.*}}.o -// LIBRARY-WEAK: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 +// LIBRARY-WEAK: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx1030 // // Check that we do not extract an unneeded hidden symbol. @@ -138,9 +138,9 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.o %t.a -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-HIDDEN -// LIBRARY-HIDDEN: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 +// LIBRARY-HIDDEN: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_70 // LIBRARY-HIDDEN-NOT: {{.*}}.o {{.*}}.o -// LIBRARY-HIDDEN: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 +// LIBRARY-HIDDEN: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx1030 // // Check that we do not extract a static library that defines a global visibile @@ -161,9 +161,9 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.o %t.a %t.a -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-GLOBAL-DEFINED -// LIBRARY-GLOBAL-DEFINED: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o +// LIBRARY-GLOBAL-DEFINED: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o // LIBRARY-GLOBAL-DEFINED-NOT: {{.*}}gfx1030{{.*}}.o -// LIBRARY-GLOBAL-DEFINED: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o +// LIBRARY-GLOBAL-DEFINED: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o // // Check that we can use --[no-]whole-archive to control extraction. @@ -185,7 +185,7 @@ int bar() { return weak; } // RUN: --linker-path=/usr/bin/ld %t.o --whole-archive %t.a -o a.out 2>&1 \ // RUN: | FileCheck %s --check-prefix=LIBRARY-WHOLE-ARCHIVE -// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o -// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o -// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_52 {{.*}}.o -// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a {{.*}}.o +// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o +// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o +// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=nvptx64-nvidia-cuda -march=sm_52 {{.*}}.o +// LIBRARY-WHOLE-ARCHIVE: clang{{.*}} -o {{.*}}.img -dumpdir {{.*}}.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a {{.*}}.o diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c index d97328b6600a8..e73fa5ca3dbf9 100644 --- a/clang/test/Driver/linker-wrapper.c +++ b/clang/test/Driver/linker-wrapper.c @@ -22,7 +22,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=NVPTX-LINK -// NVPTX-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.nvptx64.sm_70.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o +// NVPTX-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.nvptx64.sm_70.img. --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \ @@ -40,7 +40,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=AMDGPU-LINK -// AMDGPU-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// AMDGPU-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx1030 \ @@ -57,7 +57,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: not clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=SPIRV-LINK -// SPIRV-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.spirv64..img --target=spirv64-unknown-unknown {{.*}}.o --sycl-link -Xlinker -triple=spirv64-unknown-unknown -Xlinker -arch= +// SPIRV-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.spirv64..img. --target=spirv64-unknown-unknown {{.*}}.o --sycl-link -Xlinker -triple=spirv64-unknown-unknown -Xlinker -arch= // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \ @@ -68,7 +68,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld --whole-archive %t.a --no-whole-archive \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CPU-LINK -// CPU-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.x86_64..img --target=x86_64-unknown-linux-gnu -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared -Wl,--whole-archive {{.*}}.a -Wl,--no-whole-archive +// CPU-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.x86_64..img. --target=x86_64-unknown-linux-gnu -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared -Wl,--whole-archive {{.*}}.a -Wl,--no-whole-archive // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -mllvm -openmp-opt-disable \ @@ -100,8 +100,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CUDA -// CUDA: clang{{.*}} -o [[IMG_SM70:.+]] -foutput-file-base=a.out.nvptx64.sm_70.img --target=nvptx64-nvidia-cuda -march=sm_70 -// CUDA: clang{{.*}} -o [[IMG_SM52:.+]] -foutput-file-base=a.out.nvptx64.sm_52.img --target=nvptx64-nvidia-cuda -march=sm_52 +// CUDA: clang{{.*}} -o [[IMG_SM70:.+]] -dumpdir a.out.nvptx64.sm_70.img. --target=nvptx64-nvidia-cuda -march=sm_70 +// CUDA: clang{{.*}} -o [[IMG_SM52:.+]] -dumpdir a.out.nvptx64.sm_52.img. --target=nvptx64-nvidia-cuda -march=sm_52 // CUDA: fatbinary{{.*}}-64 --create {{.*}}.fatbin --image=profile=sm_70,file=[[IMG_SM70]] --image=profile=sm_52,file=[[IMG_SM52]] // CUDA: usr/bin/ld{{.*}} {{.*}}.openmp.image.{{.*}}.o {{.*}}.cuda.image.{{.*}}.o @@ -127,8 +127,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --compress --compression-level=6 \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP -// HIP: clang{{.*}} -o [[IMG_GFX90A:.+]] -foutput-file-base=a.out.amdgcn.gfx90a.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a -// HIP: clang{{.*}} -o [[IMG_GFX908:.+]] -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 +// HIP: clang{{.*}} -o [[IMG_GFX90A:.+]] -dumpdir a.out.amdgcn.gfx90a.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a +// HIP: clang{{.*}} -o [[IMG_GFX908:.+]] -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908 // HIP: clang-offload-bundler{{.*}}-type=o -bundle-align=4096 -compress -compression-level=6 -targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa--gfx90a,hip-amdgcn-amd-amdhsa--gfx908 -input={{/dev/null|NUL}} -input=[[IMG_GFX90A]] -input=[[IMG_GFX908]] -output={{.*}}.hipfb // RUN: clang-offload-packager -o %t.out \ @@ -157,7 +157,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --clang-backend \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CLANG-BACKEND -// CLANG-BACKEND: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o +// CLANG-BACKEND: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 @@ -180,8 +180,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t-on.o %t-off.o %t.a -o a.out 2>&1 | FileCheck %s --check-prefix=AMD-TARGET-ID -// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a:xnack+.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+ -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o -// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a:xnack-.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack- -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a:xnack+.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+ -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a:xnack-.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack- -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t-lib.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=generic @@ -196,8 +196,8 @@ __attribute__((visibility("protected"), used)) int x; // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t1.o %t2.o %t.a -o a.out 2>&1 | FileCheck %s --check-prefix=ARCH-ALL -// ARCH-ALL: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a.img --target=amdgcn-amd-amdhsa -mcpu=gfx90a -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o -// ARCH-ALL: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx908.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// ARCH-ALL: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o +// ARCH-ALL: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx908.img. --target=amdgcn-amd-amdhsa -mcpu=gfx908 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=x86_64-unknown-linux-gnu \ @@ -207,7 +207,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld -r %t.o \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=RELOCATABLE-LINK -// RELOCATABLE-LINK: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.x86_64..img --target=x86_64-unknown-linux-gnu +// RELOCATABLE-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.x86_64..img. --target=x86_64-unknown-linux-gnu // RELOCATABLE-LINK: /usr/bin/ld.lld{{.*}}-r // RELOCATABLE-LINK: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading @@ -219,7 +219,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld -r %t.o \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=RELOCATABLE-LINK-HIP -// RELOCATABLE-LINK-HIP: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.amdgcn.gfx90a.img --target=amdgcn-amd-amdhsa +// RELOCATABLE-LINK-HIP: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a.img. --target=amdgcn-amd-amdhsa // RELOCATABLE-LINK-HIP: clang-offload-bundler{{.*}} -type=o -bundle-align=4096 -targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa--gfx90a -input={{/dev/null|NUL}} -input={{.*}} -output={{.*}} // RELOCATABLE-LINK-HIP: /usr/bin/ld.lld{{.*}}-r // RELOCATABLE-LINK-HIP: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading @@ -233,7 +233,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld -r %t.o \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=RELOCATABLE-LINK-CUDA -// RELOCATABLE-LINK-CUDA: clang{{.*}} -o {{.*}}.img -foutput-file-base=a.out.nvptx64.sm_89.img --target=nvptx64-nvidia-cuda +// RELOCATABLE-LINK-CUDA: clang{{.*}} -o {{.*}}.img -dumpdir a.out.nvptx64.sm_89.img. --target=nvptx64-nvidia-cuda // RELOCATABLE-LINK-CUDA: fatbinary{{.*}} -64 --create {{.*}}.fatbin --image=profile=sm_89,file={{.*}}.img // RELOCATABLE-LINK-CUDA: /usr/bin/ld.lld{{.*}}-r // RELOCATABLE-LINK-CUDA: llvm-objcopy{{.*}}a.out --remove-section .llvm.offloading diff --git a/clang/test/Driver/lto-dwo.c b/clang/test/Driver/lto-dwo.c index 206d4cba7f2a9..50727656b3289 100644 --- a/clang/test/Driver/lto-dwo.c +++ b/clang/test/Driver/lto-dwo.c @@ -1,9 +1,25 @@ // Confirm that -gsplit-dwarf=DIR is passed to linker -// RUN: %clang --target=x86_64-unknown-linux -### %s -flto=thin -gsplit-dwarf -o a.out 2> %t +// DEFINE: %{RUN-ELF} = %clang --target=x86_64-unknown-linux -### %s \ +// DEFINE: -flto=thin -gsplit-dwarf + +// RUN: %{RUN-ELF} -o a.out 2> %t // RUN: FileCheck -check-prefix=CHECK-LINK-ELF-DWO-DIR-DEFAULT < %t %s // RUN: %clang_cl --target=x86_64-unknown-windows-msvc -### -fuse-ld=lld -flto -gsplit-dwarf -o a.out -- %s 2> %t // RUN: FileCheck -check-prefix=CHECK-LINK-COFF-DWO-DIR-DEFAULT < %t %s // -// CHECK-LINK-ELF-DWO-DIR-DEFAULT: "-plugin-opt=dwo_dir=a.out_dwo" +// CHECK-LINK-ELF-DWO-DIR-DEFAULT: "-plugin-opt=dwo_dir=a.out-dwo" // CHECK-LINK-COFF-DWO-DIR-DEFAULT: "/dwodir:a.out_dwo" + +// Check -dumpdir effect on -gsplit-dwarf. +// +// DEFINE: %{RUN-DUMPDIR} = %{RUN-ELF} -dumpdir /dir/file.ext +// +// RUN: %{RUN-ELF} 2>&1 | FileCheck %s -check-prefix=CHECK-NO-O +// RUN: %{RUN-ELF} -o FOO 2>&1 | FileCheck %s -check-prefix=CHECK-O +// RUN: %{RUN-DUMPDIR} 2>&1 | FileCheck %s -check-prefix=CHECK-DUMPDIR +// RUN: %{RUN-DUMPDIR} -o FOO 2>&1 | FileCheck %s -check-prefix=CHECK-DUMPDIR +// +// CHECK-NO-O: "-plugin-opt=dwo_dir=a-dwo" +// CHECK-O: "-plugin-opt=dwo_dir=FOO-dwo" +// CHECK-DUMPDIR: "-plugin-opt=dwo_dir=/dir/file.extdwo" diff --git a/clang/test/Driver/opt-record.c b/clang/test/Driver/opt-record.c index c648bf80fabeb..86d00d5612647 100644 --- a/clang/test/Driver/opt-record.c +++ b/clang/test/Driver/opt-record.c @@ -58,12 +58,12 @@ // CHECK-NOPASS-NOT: "-plugin-opt=opt-remarks-format=yaml" // CHECK-NOPASS-NOT: "-plugin-opt=opt-remarks-hotness-threshold=100" -// CHECK-PASS-A: "-plugin-opt=opt-remarks-filename=a.out.opt.ld.yaml" +// CHECK-PASS-A: "-plugin-opt=opt-remarks-filename=a-opt.ld.yaml" // CHECK-PASS-A-SAME: "-plugin-opt=opt-remarks-passes=inline" // CHECK-PASS-A-SAME: "-plugin-opt=opt-remarks-format=yaml" // CHECK-PASS-A-SAME: "-plugin-opt=opt-remarks-hotness-threshold=100" -// CHECK-PASS: "-plugin-opt=opt-remarks-filename=FOO.opt.ld.yaml" +// CHECK-PASS: "-plugin-opt=opt-remarks-filename=FOO-opt.ld.yaml" // CHECK-PASS-SAME: "-plugin-opt=opt-remarks-passes=inline" // CHECK-PASS-SAME: "-plugin-opt=opt-remarks-format=yaml" // CHECK-PASS-SAME: "-plugin-opt=opt-remarks-hotness-threshold=100" @@ -79,40 +79,16 @@ // CHECK-PASS-AUTO: "-plugin-opt=opt-remarks-hotness-threshold=auto" -// Check -foutput-file-base effect on -foptimization-record-file and -// -gsplit-dwarf. +// Check -dumpdir effect on -foptimization-record-file. // -// DEFINE: %{RUN-BASE} = \ +// DEFINE: %{RUN-DUMPDIR} = \ // DEFINE: %clang --target=x86_64-linux -### -fuse-ld=lld -B%S/Inputs/lld \ -// DEFINE: -flto -fsave-optimization-record -gsplit-dwarf %s +// DEFINE: -flto -fsave-optimization-record -dumpdir /dir/file.ext %s // -// RUN: %{RUN-BASE} 2>&1 | FileCheck %s -check-prefix=CHECK-BASE-NONE +// RUN: %{RUN-DUMPDIR} 2>&1 | FileCheck %s -check-prefix=CHECK-DUMPDIR +// RUN: %{RUN-DUMPDIR} -o FOO 2>&1 | FileCheck %s -check-prefix=CHECK-DUMPDIR +// RUN: %{RUN-DUMPDIR} -foptimization-record-file=user-file.ext 2>&1 | \ +// RUN: FileCheck %s -check-prefix=CHECK-DUMPDIR-IGNORE // -// RUN: %{RUN-BASE} -o FOO 2>&1 | FileCheck %s -check-prefix=CHECK-BASE-O -// -// RUN: %{RUN-BASE} -foutput-file-base=/dir/file.ext 2>&1 | \ -// RUN: FileCheck %s -check-prefix=CHECK-BASE -// -// RUN: %{RUN-BASE} -o FOO -foutput-file-base=/dir/file.ext 2>&1 | \ -// RUN: FileCheck %s -check-prefix=CHECK-BASE -// -// There is currently no option to ignore -foutput-file-base in the case of -// -gsplit-dwarf. -// RUN: %{RUN-BASE} -foutput-file-base=/dir/file.ext \ -// RUN: -foptimization-record-file=user-file.ext 2>&1 | \ -// RUN: FileCheck %s -check-prefix=CHECK-BASE-IGNORE -// -// CHECK-BASE-NONE: "-plugin-opt=dwo_dir=a.out_dwo" -// CHECK-BASE-NONE-SAME: "-plugin-opt=opt-remarks-filename=a.out.opt.ld.yaml" -// CHECK-BASE-NONE-SAME: "-plugin-opt=opt-remarks-format=yaml" -// -// CHECK-BASE-O: "-plugin-opt=dwo_dir=FOO_dwo" -// CHECK-BASE-O-SAME: "-plugin-opt=opt-remarks-filename=FOO.opt.ld.yaml" -// CHECK-BASE-O-SAME: "-plugin-opt=opt-remarks-format=yaml" -// -// CHECK-BASE: "-plugin-opt=dwo_dir=/dir/file.ext_dwo" -// CHECK-BASE-SAME: "-plugin-opt=opt-remarks-filename=/dir/file.ext.opt.ld.yaml" -// CHECK-BASE-SAME: "-plugin-opt=opt-remarks-format=yaml" -// -// CHECK-BASE-IGNORE: "-plugin-opt=opt-remarks-filename=user-file.ext.opt.ld.yaml" -// CHECK-BASE-IGNORE-SAME: "-plugin-opt=opt-remarks-format=yaml" +// CHECK-DUMPDIR: "-plugin-opt=opt-remarks-filename=/dir/file.extopt.ld.yaml" +// CHECK-DUMPDIR-IGNORE: "-plugin-opt=opt-remarks-filename=user-file.ext.opt.ld.yaml" diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 8a459efc843b4..1d91f5f255f18 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -16,7 +16,6 @@ #include "clang/Basic/TargetID.h" #include "clang/Basic/Version.h" -#include "clang/Driver/Options.h" #include "llvm/ADT/MapVector.h" #include "llvm/BinaryFormat/Magic.h" #include "llvm/Bitcode/BitcodeWriter.h" @@ -487,8 +486,12 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args, "--no-default-config", "-o", *TempFileOrErr, - Args.MakeArgString("-foutput-file-base=" + ExecutableName + - OutputFileBase + ".img"), + // Without -dumpdir, Clang will place auxiliary output files in the + // temporary directory of TempFileOrErr, where they will not easily be + // found by the user and might eventually be automatically removed. Tell + // Clang to instead place them alongside the final executable. + "-dumpdir", + Args.MakeArgString(ExecutableName + OutputFileBase + ".img."), Args.MakeArgString("--target=" + Triple.getTriple()), }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits