llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-driver Author: ivarusic-amd <details> <summary>Changes</summary> When compiling HIP for multiple offload archs with clang-cl's /Fo (e.g. --offload-arch=gfx900 --offload-arch=gfx90a:xnack+ /Fo:out.obj), every arch's intermediate device compile job wrote to the same literal /Fo path, so each arch silently overwrote theprevious one's object before packaging so only one arch's code ended up in the final binary. Root cause: in GetNamedOutputPath(), the "output to a temp file" gate falls through to the literal user-specified path for -o only when AtTopLevel is true; intermediate (non-top-level) -o actions get a genuinely unique temp path. /Fo was unconditionally excluded from this gate regardless of AtTopLevel, so intermediate offloading-device sub-actions used the literal /Fo path directly instead. Fix: narrow the /Fo exclusion so it only bypasses the temp-file route for non-offloading (host) actions - offloading device sub-actions under /Fo now fall through to CreateTempOutputPath, matching how -o already behaves. Final top-level output still honors the literal /Fo path. Added clang/test/Driver/hip-windows-multiarch-fo.hip, verified to fail before the fix --- Full diff: https://github.com/llvm/llvm-project/pull/215663.diff 2 Files Affected: - (modified) clang/lib/Driver/Driver.cpp (+8-1) - (added) clang/test/Driver/hip-windows-multiarch-fo.hip (+20) ``````````diff diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index d4719f37e5b4d..158d9fb1beae6 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -6692,8 +6692,15 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, } // Output to a temporary file? + // /Fo is normally exempted from this so that its literal path is honored, + // but offloading device sub-actions (e.g. each arch of a multi-arch HIP + // compile) are not the final output and must still get a unique path here, + // the same way they would under -o; otherwise every arch collides on the + // single /Fo path. if ((!AtTopLevel && !isSaveTempsEnabled() && - !C.getArgs().hasArg(options::OPT__SLASH_Fo)) || + !(C.getArgs().hasArg(options::OPT__SLASH_Fo) && + (JA.getOffloadingDeviceKind() == Action::OFK_None || + JA.getOffloadingDeviceKind() == Action::OFK_Host))) || CCGenDiagnostics) { StringRef Name = llvm::sys::path::filename(BaseInput); return CreateTempOutputPath(Name.split('.').first); diff --git a/clang/test/Driver/hip-windows-multiarch-fo.hip b/clang/test/Driver/hip-windows-multiarch-fo.hip new file mode 100644 index 0000000000000..b997f233427fc --- /dev/null +++ b/clang/test/Driver/hip-windows-multiarch-fo.hip @@ -0,0 +1,20 @@ +// REQUIRES: system-windows +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// Each offload-arch device compile job must get its own unique output path +// under /Fo, the same way -o already does via GetNamedOutputPath's temp-file +// gate. Otherwise every arch's device object collides on the single literal +// /Fo path and silently overwrites the others before packaging. + +// RUN: %clang_cl -### --target=x86_64-pc-windows-msvc -x hip \ +// RUN: --offload-arch=gfx900 --offload-arch=gfx90a:xnack+ \ +// RUN: -nogpuinc -nogpulib -Foout.obj -- %s 2>&1 | FileCheck %s + +// CHECK: "-target-cpu" "gfx900"{{.*}}"-o" "{{.*}}gfx900-{{[^"]*}}" +// CHECK-NOT: "-o" "out.obj" +// CHECK: "-target-cpu" "gfx90a" "-mxnack"{{.*}}"-o" "{{.*}}gfx90a@xnack+-{{[^"]*}}" +// CHECK-NOT: "-o" "out.obj" +// CHECK: "-o" "out.obj" + +void main() {} `````````` </details> https://github.com/llvm/llvm-project/pull/215663 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
