Author: Joseph Huber Date: 2026-07-08T07:26:34-05:00 New Revision: fd86339aa29c096855b9cfba4a44c539a013ba15
URL: https://github.com/llvm/llvm-project/commit/fd86339aa29c096855b9cfba4a44c539a013ba15 DIFF: https://github.com/llvm/llvm-project/commit/fd86339aa29c096855b9cfba4a44c539a013ba15.diff LOG: [LinkerWrapper] Fix AMDGPU Target-IDs linking in improper order (#207853) Summary: These target IDs are supposed to be ordered from most to least specific, but we had no such ordering. The changes basically sort the input from least to most specific using the target-id presence, then ensures that their entries are listed first. Fixes: https://github.com/llvm/llvm-project/issues/207835 Added: Modified: clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper.c clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp Removed: ################################################################################ diff --git a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper.c b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper.c index a19a11e87afdb..0e018dc3af8c9 100644 --- a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper.c +++ b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper.c @@ -185,6 +185,22 @@ __attribute__((visibility("protected"), used)) int x; // AMD-TARGET-ID: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a:xnack+.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+ -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- -Wl,--no-undefined {{.*}}.o {{.*}}.o +// RUN: llvm-offload-binary -o %t-generic.out \ +// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t-generic.o -fembed-offload-object=%t-generic.out +// RUN: llvm-offload-binary -o %t-on.out \ +// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a:xnack+ +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t-on.o -fembed-offload-object=%t-on.out +// RUN: llvm-offload-binary -o %t-off.out \ +// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a:xnack- +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t-off.o -fembed-offload-object=%t-off.out +// 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-generic.o -o a.out 2>&1 | FileCheck %s --check-prefix=AMD-GENERIC-MERGE + +// AMD-GENERIC-MERGE-NOT: -mcpu=gfx90a -Wl,--no-undefined +// AMD-GENERIC-MERGE: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a:xnack+.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack+ -Wl,--no-undefined {{.*}}.o {{.*}}.o +// AMD-GENERIC-MERGE: clang{{.*}} -o {{.*}}.img -dumpdir a.out.amdgcn.gfx90a:xnack-.img. --target=amdgcn-amd-amdhsa -mcpu=gfx90a:xnack- -Wl,--no-undefined {{.*}}.o {{.*}}.o + // RUN: llvm-offload-binary -o %t-lib.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=generic // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t-lib.out diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 5abda37ada7fb..0e30dfca64c60 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1398,17 +1398,30 @@ getDeviceInput(const ArgList &Args) { } } + // Handle the most specific target-ids first so a generic input merges last. + llvm::stable_sort(ObjectFilesToExtract, + [](const OffloadFile &A, const OffloadFile &B) { + return A.getBinary()->getArch().count(':') > + B.getBinary()->getArch().count(':'); + }); + // Link all standard input files and update the list of symbols. MapVector<OffloadFile::TargetID, SmallVector<OffloadFile, 0>> InputFiles; for (OffloadFile &Binary : ObjectFilesToExtract) { if (!Binary.getBinary()) continue; - SmallVector<OffloadFile::TargetID> CompatibleTargets = {Binary}; + OffloadFile::TargetID Target = Binary; + SmallVector<OffloadFile::TargetID> CompatibleTargets; for (const auto &[ID, Input] : InputFiles) - if (object::areTargetsCompatible(Binary, ID)) + if (Target.first == ID.first && + clang::isCompatibleTargetID(Target.second, ID.second)) CompatibleTargets.emplace_back(ID); + // Seed a new image when no existing target can provide for this input. + if (CompatibleTargets.empty()) + CompatibleTargets.emplace_back(Target); + for (const auto &[Index, ID] : llvm::enumerate(CompatibleTargets)) { // If another target needs this binary it must be copied instead. if (Index == CompatibleTargets.size() - 1) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
