https://github.com/yxsamliu updated 
https://github.com/llvm/llvm-project/pull/206350

>From 5ecbbc0ee7ad5dac6498471f803784124ea23da2 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <[email protected]>
Date: Fri, 26 Jun 2026 13:29:24 -0400
Subject: [PATCH] [HIP] Remove redundant device optimization pipeline

The new offload driver uses the linker wrapper for HIP device codegen. In 
default non-RDC mode, the wrapper uses the non-LTO path (`--no-lto`) and 
compiles device bitcode to ISA through the normal optimization pipeline.

Do not run the LLVM optimizer in the earlier HIP device cc1 job when it only 
produces intermediate bitcode for this default non-RDC path. This avoids a 
non-parallel redundant optimization pipeline and reduces compile time.

Keep the optimizer for RDC and explicit offload LTO, where the LTO flow expects 
optimized input bitcode. Also keep it when the user requests final LLVM output 
with `-emit-llvm`, so the requested optimization level is honored.

The linker wrapper now writes extracted bitcode with a bitcode suffix for this 
non-LTO path, so clang classifies the input naturally and the wrapper no longer 
needs to force `-x ir`.
---
 clang/lib/Driver/ToolChains/Clang.cpp         | 25 ++++++++++-
 .../hip-new-driver-disable-llvm-passes.hip    | 43 +++++++++++++++++++
 .../linker-wrapper-hip-no-rdc.c               |  9 ++--
 .../ClangLinkerWrapper.cpp                    | 25 ++++++-----
 4 files changed, 84 insertions(+), 18 deletions(-)
 create mode 100644 clang/test/Driver/hip-new-driver-disable-llvm-passes.hip

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index bb3fbc3c585a6..f011bebfc6919 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5428,6 +5428,28 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
           CmdArgs.push_back("-flto-unit");
       }
     }
+
+    // Default non-RDC HIP uses the linker wrapper's non-LTO compile path for
+    // device bitcode. Skip the early cc1 optimizer so the overall flow has one
+    // classic optimization pipeline. Keep optimized bitcode when the wrapper
+    // uses an LTO-dependent path, such as RDC, explicit offload LTO, or 
profile
+    // generation. Also keep it for final -emit-llvm output.
+    bool HIPUsesDefaultNonRDCNonLTO =
+        IsHIPDevice && !IsRDCMode &&
+        !Args.hasArg(options::OPT_foffload_lto_EQ,
+                     options::OPT_fno_offload_lto) &&
+        !Args.hasArg(options::OPT_fprofile_generate,
+                     options::OPT_fprofile_generate_EQ,
+                     options::OPT_fprofile_instr_generate,
+                     options::OPT_fprofile_instr_generate_EQ) &&
+        !Triple.isSPIRV();
+    if ((JA.getType() == types::TY_LLVM_BC ||
+         JA.getType() == types::TY_LTO_BC) &&
+        HIPUsesDefaultNonRDCNonLTO && !Args.hasArg(options::OPT_emit_llvm) &&
+        Args.hasFlag(options::OPT_offload_new_driver,
+                     options::OPT_no_offload_new_driver,
+                     C.getActiveOffloadKinds() != Action::OFK_None))
+      CmdArgs.push_back("-disable-llvm-passes");
   }
 
   Args.AddLastArg(CmdArgs, options::OPT_dumpdir);
@@ -9789,7 +9811,8 @@ void LinkerWrapper::ConstructJob(Compilation &C, const 
JobAction &JA,
 
       if (JA.getType() == types::TY_HIP_FATBIN && Kind == Action::OFK_HIP) {
         // Non-RDC HIP uses the conventional non-LTO pipeline unless the user
-        // opts into offload LTO.
+        // opts into offload LTO or requests profile generation, which depends
+        // on LTO.
         bool UsesProfileGenerate = Args.hasArg(
             options::OPT_fprofile_generate, options::OPT_fprofile_generate_EQ,
             options::OPT_fprofile_instr_generate,
diff --git a/clang/test/Driver/hip-new-driver-disable-llvm-passes.hip 
b/clang/test/Driver/hip-new-driver-disable-llvm-passes.hip
new file mode 100644
index 0000000000000..776c6ab837d8c
--- /dev/null
+++ b/clang/test/Driver/hip-new-driver-disable-llvm-passes.hip
@@ -0,0 +1,43 @@
+// RUN: %clang -### --target=x86_64-linux-gnu \
+// RUN:   --offload-arch=gfx90a -nogpuinc -nogpulib \
+// RUN:   -O3 -c -x hip %s 2>&1 | FileCheck -check-prefix=DEFAULT %s
+// RUN: %clang -### --target=x86_64-linux-gnu \
+// RUN:   --offload-arch=gfx90a -nogpuinc -nogpulib -fgpu-rdc \
+// RUN:   -O3 -c -x hip %s 2>&1 | FileCheck -check-prefix=RDC %s
+// RUN: %clang -### --target=x86_64-linux-gnu \
+// RUN:   --offload-arch=gfx90a -nogpuinc -nogpulib -foffload-lto \
+// RUN:   -O3 -c -x hip %s 2>&1 | FileCheck -check-prefix=LTO %s
+// RUN: %clang -### --target=x86_64-linux-gnu \
+// RUN:   --offload-arch=gfx90a -nogpuinc -nogpulib \
+// RUN:   -O3 --cuda-device-only -emit-llvm -c -x hip %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=USER-BC %s
+// RUN: %clang -### --target=x86_64-linux-gnu \
+// RUN:   --offload-arch=gfx90a -nogpuinc -nogpulib \
+// RUN:   -O3 --cuda-device-only -emit-llvm -S -x hip %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=USER-IR %s
+
+// DEFAULT: "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// DEFAULT-SAME: "-emit-llvm-bc"
+// DEFAULT-SAME: "-disable-llvm-passes"
+// DEFAULT: "{{.*}}llvm-offload-binary"
+// DEFAULT: "{{.*}}clang-linker-wrapper"
+// DEFAULT-SAME: "--no-lto"
+
+// RDC: "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// RDC-SAME: "-emit-llvm-bc"
+// RDC-SAME: "-flto=full"
+// RDC-NOT: "-disable-llvm-passes"
+
+// LTO: "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// LTO-SAME: "-emit-llvm-bc"
+// LTO-SAME: "-flto=full"
+// LTO-NOT: "-disable-llvm-passes"
+// LTO: "{{.*}}clang-linker-wrapper"
+
+// USER-BC: "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// USER-BC-SAME: "-emit-llvm-bc"
+// USER-BC-NOT: "-disable-llvm-passes"
+
+// USER-IR: "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// USER-IR-SAME: "-emit-llvm"
+// USER-IR-NOT: "-disable-llvm-passes"
diff --git 
a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc.c 
b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc.c
index 80ac493825aad..27328bef4a3fc 100644
--- a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc.c
+++ b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc.c
@@ -62,8 +62,9 @@ __attribute__((visibility("protected"), used)) int x;
 // LTO: clang{{.*}} -mcpu=gfx1200
 
 // With --no-lto the AMDGPU device compilation uses the conventional non-LTO
-// pipeline: -flto must not be passed, and '-x ir' must be passed so Clang
-// compiles the bitcode (stored in an object-extension file) instead of
-// handing it to the LTO link.
+// pipeline. Extracted bitcode keeps a bitcode extension so Clang compiles it
+// without forcing the input language.
 // RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu 
--wrapper-verbose --dry-run --no-lto --emit-fatbin-only 
--linker-path=/usr/bin/ld %t.out -o %t.nolto.hipfb 2>&1 | FileCheck %s 
--check-prefix=NO-LTO
-// NO-LTO: clang{{.*}} -mcpu=gfx1200{{.*}} -x ir {{.*}}-flto=none
+// NO-LTO: clang{{.*}} -mcpu=gfx1200
+// NO-LTO-NOT: -x
+// NO-LTO-SAME: {{.*}}.bc{{.*}}-flto=none
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp 
b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index a4a67eed7d47f..06399809af52b 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -543,16 +543,6 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, 
const ArgList &Args,
   if (!Triple.isNVPTX() && !Triple.isSPIRV())
     CmdArgs.push_back("-Wl,--no-undefined");
 
-  // The device inputs are bitcode stored in files with an object extension.
-  // Force the IR input language so Clang runs the compile and backend phases
-  // instead of treating them as linker inputs, which would defer codegen to
-  // the LTO link and defeat the non-LTO pipeline.
-  // FIXME: This is a stop-gap for non-RDC. Longer term, RDC and non-RDC should
-  //        share a unified interface.
-  // SPIR-V has no non-LTO pipeline so a --no-lto leaked from a concrete arch 
in
-  // a multi-target compile is ignored. Which is a workaround to remove.
-  if (Args.hasArg(OPT_no_lto) && !Triple.isSPIRV())
-    CmdArgs.append({"-x", "ir"});
   for (StringRef InputFile : InputFiles)
     CmdArgs.push_back(InputFile);
 
@@ -658,7 +648,8 @@ Error containerizeRawImage(std::unique_ptr<MemoryBuffer> 
&Img, OffloadKind Kind,
   return Error::success();
 }
 
-Expected<StringRef> writeOffloadFile(const OffloadFile &File) {
+Expected<StringRef> writeOffloadFile(const OffloadFile &File,
+                                     bool PreserveBitcodeExtension) {
   const OffloadBinary &Binary = *File.getBinary();
 
   StringRef Prefix =
@@ -666,7 +657,12 @@ Expected<StringRef> writeOffloadFile(const OffloadFile 
&File) {
   SmallString<128> Filename;
   (Prefix + "-" + Binary.getTriple() + "-" + Binary.getArch())
       .toVector(Filename);
-  auto TempFileOrErr = createOutputFile(Filename, "o");
+  StringRef Extension =
+      PreserveBitcodeExtension &&
+              identify_magic(Binary.getImage()) == file_magic::bitcode
+          ? "bc"
+          : "o";
+  auto TempFileOrErr = createOutputFile(Filename, Extension);
   if (!TempFileOrErr)
     return TempFileOrErr.takeError();
 
@@ -1003,6 +999,9 @@ linkAndWrapDeviceFiles(ArrayRef<SmallVector<OffloadFile>> 
LinkerInputFiles,
           reportError(createStringError(Err));
         });
     auto LinkerArgs = getLinkerArgs(Input, BaseArgs);
+    bool PreserveBitcodeExtension =
+        LinkerArgs.hasArg(OPT_no_lto) &&
+        !llvm::Triple(LinkerArgs.getLastArgValue(OPT_triple_EQ)).isSPIRV();
 
     uint16_t ActiveOffloadKindMask = 0u;
     for (const auto &File : Input)
@@ -1019,7 +1018,7 @@ linkAndWrapDeviceFiles(ArrayRef<SmallVector<OffloadFile>> 
LinkerInputFiles,
     // Write any remaining device inputs to an output file.
     SmallVector<StringRef> InputFiles;
     for (const OffloadFile &File : Input) {
-      auto FileNameOrErr = writeOffloadFile(File);
+      auto FileNameOrErr = writeOffloadFile(File, PreserveBitcodeExtension);
       if (!FileNameOrErr)
         return FileNameOrErr.takeError();
       InputFiles.emplace_back(*FileNameOrErr);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to