https://github.com/AdityaSinha149 updated 
https://github.com/llvm/llvm-project/pull/231783

>From ebec042c12844bb47fd08531b341c2aac3401ecb Mon Sep 17 00:00:00 2001
From: AdityaSinha149 <[email protected]>
Date: Tue, 13 Oct 2026 11:57:25 +0530
Subject: [PATCH 1/2] [clang-repl] Add OffloadType enum and HIP device parser
 skeleton

---
 clang/include/clang/Interpreter/Interpreter.h |  8 ++++++
 clang/lib/Interpreter/DeviceOffload.cpp       | 27 +++++++++++++++++++
 clang/lib/Interpreter/DeviceOffload.h         | 16 ++++++++++-
 clang/lib/Interpreter/Interpreter.cpp         | 24 ++++++++++++++---
 4 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index a598574b417c0..64f02b797c204 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -46,6 +46,10 @@ class Decl;
 class IncrementalParser;
 class IncrementalDeviceParser;
 
+/// The device language to offload to. \c Detect selects the vendor of the
+/// device available on the machine.
+enum class OffloadType { Detect, CUDA, HIP };
+
 /// Create a pre-configured \c CompilerInstance for incremental processing.
 class IncrementalCompilerBuilder {
   using DriverCompilationFn = llvm::Error(const driver::Compilation &);
@@ -147,6 +151,10 @@ class Interpreter {
   create(std::unique_ptr<CompilerInstance> CI,
          std::unique_ptr<IncrementalExecutorBuilder> IEB = nullptr);
   static llvm::Expected<std::unique_ptr<Interpreter>>
+  createWithDevice(std::unique_ptr<CompilerInstance> CI,
+                   std::unique_ptr<CompilerInstance> DCI,
+                   OffloadType Type = OffloadType::Detect);
+  static llvm::Expected<std::unique_ptr<Interpreter>>
   createWithCUDA(std::unique_ptr<CompilerInstance> CI,
                  std::unique_ptr<CompilerInstance> DCI);
 
diff --git a/clang/lib/Interpreter/DeviceOffload.cpp 
b/clang/lib/Interpreter/DeviceOffload.cpp
index e5887bc9c8841..3f416a1918e24 100644
--- a/clang/lib/Interpreter/DeviceOffload.cpp
+++ b/clang/lib/Interpreter/DeviceOffload.cpp
@@ -36,6 +36,33 @@ IncrementalDeviceParser::IncrementalDeviceParser(
 
 IncrementalDeviceParser::~IncrementalDeviceParser() {}
 
+IncrementalHIPDeviceParser::IncrementalHIPDeviceParser(
+    CompilerInstance &DeviceInstance, CompilerInstance &HostInstance,
+    IncrementalAction *DeviceAct,
+    llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS,
+    llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs)
+    : IncrementalDeviceParser(DeviceInstance, HostInstance, DeviceAct, FS, Err,
+                              PTUs) {
+  if (Err)
+    return;
+  StringRef Arch = TargetOpts.CPU;
+  if (!Arch.starts_with("gfx")) {
+    Err = llvm::joinErrors(std::move(Err), llvm::make_error<llvm::StringError>(
+                                               "Invalid HIP architecture",
+                                               
llvm::inconvertibleErrorCode()));
+    return;
+  }
+}
+
+llvm::Error IncrementalHIPDeviceParser::GenerateOffloadBinary() {
+  // FIXME: Generate the HSACO and bundle it for the host compilation.
+  return llvm::make_error<llvm::StringError>(
+      "HIP offload binary generation is not supported yet.",
+      llvm::inconvertibleErrorCode());
+}
+
+IncrementalHIPDeviceParser::~IncrementalHIPDeviceParser() {}
+
 IncrementalCUDADeviceParser::IncrementalCUDADeviceParser(
     CompilerInstance &DeviceInstance, CompilerInstance &HostInstance,
     IncrementalAction *DeviceAct,
diff --git a/clang/lib/Interpreter/DeviceOffload.h 
b/clang/lib/Interpreter/DeviceOffload.h
index fc780ef64add8..0275c0e10cda8 100644
--- a/clang/lib/Interpreter/DeviceOffload.h
+++ b/clang/lib/Interpreter/DeviceOffload.h
@@ -6,7 +6,7 @@
 //
 
//===----------------------------------------------------------------------===//
 //
-// This file defines a base class required for offloading to devices.
+// This file defines the classes required for offloading to devices.
 //
 
//===----------------------------------------------------------------------===//
 
@@ -44,6 +44,20 @@ class IncrementalDeviceParser : public IncrementalParser {
   const TargetOptions &TargetOpts;
 };
 
+class IncrementalHIPDeviceParser : public IncrementalDeviceParser {
+
+public:
+  IncrementalHIPDeviceParser(
+      CompilerInstance &DeviceInstance, CompilerInstance &HostInstance,
+      IncrementalAction *DeviceAct,
+      llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS,
+      llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs);
+
+  llvm::Error GenerateOffloadBinary() override;
+
+  ~IncrementalHIPDeviceParser() override;
+};
+
 class IncrementalCUDADeviceParser : public IncrementalDeviceParser {
 
 public:
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index a8e54d62864b5..9bd711c24be26 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -479,6 +479,18 @@ llvm::Expected<std::unique_ptr<Interpreter>> 
Interpreter::create(
 llvm::Expected<std::unique_ptr<Interpreter>>
 Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
                             std::unique_ptr<CompilerInstance> DCI) {
+  return createWithDevice(std::move(CI), std::move(DCI), OffloadType::CUDA);
+}
+
+llvm::Expected<std::unique_ptr<Interpreter>>
+Interpreter::createWithDevice(std::unique_ptr<CompilerInstance> CI,
+                              std::unique_ptr<CompilerInstance> DCI,
+                              OffloadType Type) {
+  if (Type == OffloadType::Detect)
+    return llvm::make_error<llvm::StringError>(
+        "Detecting the device vendor is not supported yet.",
+        llvm::inconvertibleErrorCode());
+
   // avoid writing fat binary to disk using an in-memory virtual file system
   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS =
       std::make_unique<llvm::vfs::InMemoryFileSystem>();
@@ -515,9 +527,15 @@ 
Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
 
   Interp->DeviceCI = std::move(DCI);
 
-  auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
-      *Interp->DeviceCI, *Interp->getCompilerInstance(),
-      Interp->DeviceAct.get(), IMVFS, Err, Interp->PTUs);
+  std::unique_ptr<IncrementalDeviceParser> DeviceParser;
+  if (Type == OffloadType::HIP)
+    DeviceParser = std::make_unique<IncrementalHIPDeviceParser>(
+        *Interp->DeviceCI, *Interp->getCompilerInstance(),
+        Interp->DeviceAct.get(), IMVFS, Err, Interp->PTUs);
+  else
+    DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
+        *Interp->DeviceCI, *Interp->getCompilerInstance(),
+        Interp->DeviceAct.get(), IMVFS, Err, Interp->PTUs);
 
   if (Err)
     return std::move(Err);

>From 1b5d621a88ae8ba7564165ba984551aff2e6ede5 Mon Sep 17 00:00:00 2001
From: AdityaSinha149 <[email protected]>
Date: Wed, 14 Oct 2026 13:00:27 +0530
Subject: [PATCH 2/2] [clang-repl] Added -hip option

---
 clang/include/clang/Interpreter/Interpreter.h | 33 +++++++++++--
 clang/lib/Interpreter/Interpreter.cpp         | 39 +++++++++------
 .../Interpreter/HIP/hip-not-supported.hip     | 11 +++++
 clang/test/Interpreter/HIP/lit.local.cfg      | 12 +++++
 clang/tools/clang-repl/ClangRepl.cpp          | 49 ++++++++++++-------
 5 files changed, 106 insertions(+), 38 deletions(-)
 create mode 100644 clang/test/Interpreter/HIP/hip-not-supported.hip
 create mode 100644 clang/test/Interpreter/HIP/lit.local.cfg

diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 64f02b797c204..0a147ae745662 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -69,29 +69,52 @@ class IncrementalCompilerBuilder {
   // Offload options
   void SetOffloadArch(llvm::StringRef Arch) { OffloadArch = Arch; };
 
-  // CUDA specific
-  void SetCudaSDK(llvm::StringRef path) { CudaSDKPath = path; };
+  void SetDeviceSDK(OffloadType Type, llvm::StringRef Path) {
+    if (Type == OffloadType::HIP)
+      RocmSDKPath = Path;
+    else if (Type == OffloadType::CUDA)
+      CudaSDKPath = Path;
+  }
+
+  // Retained for compatibility with existing CUDA callers.
+  void SetCudaSDK(llvm::StringRef Path) {
+    SetDeviceSDK(OffloadType::CUDA, Path);
+  }
 
   // Hand over the compilation.
   void SetDriverCompilationCallback(std::function<DriverCompilationFn> C) {
     CompilationCB = C;
   }
 
-  llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaHost();
-  llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaDevice();
+  llvm::Expected<std::unique_ptr<CompilerInstance>>
+  CreateHost(OffloadType Type);
+  llvm::Expected<std::unique_ptr<CompilerInstance>>
+  CreateDevice(OffloadType Type);
+
+  // Retained for compatibility with existing CUDA callers.
+  llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaHost() {
+    return CreateHost(OffloadType::CUDA);
+  }
+  llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaDevice() {
+    return CreateDevice(OffloadType::CUDA);
+  }
 
 private:
   llvm::Expected<std::unique_ptr<CompilerInstance>>
   create(std::string TT, std::vector<const char *> &ClangArgv);
 
-  llvm::Expected<std::unique_ptr<CompilerInstance>> createCuda(bool device);
+  llvm::Expected<std::unique_ptr<CompilerInstance>>
+  createOffload(bool device, OffloadType Type);
 
   std::vector<const char *> UserArgs;
   std::optional<std::string> TargetTriple;
 
   llvm::StringRef OffloadArch;
+  llvm::StringRef RocmSDKPath;
   llvm::StringRef CudaSDKPath;
 
+  std::string OffloadCUID;
+
   std::optional<std::function<DriverCompilationFn>> CompilationCB;
 };
 
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index 9bd711c24be26..a902afc2b97ac 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -45,12 +45,14 @@
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ModuleCache.h"
 #include "clang/Serialization/ObjectFilePCHContainerReader.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Host.h"
@@ -304,19 +306,22 @@ IncrementalCompilerBuilder::CreateCpp() {
 }
 
 llvm::Expected<std::unique_ptr<CompilerInstance>>
-IncrementalCompilerBuilder::createCuda(bool device) {
+IncrementalCompilerBuilder::createOffload(bool device, OffloadType Type = 
OffloadType::Detect) {
+  if (Type == OffloadType::Detect)
+    return llvm::make_error<llvm::StringError>(
+        "Detecting the device vendor is not supported yet.",
+        llvm::inconvertibleErrorCode());
+
+  const bool HipEnabled = Type == OffloadType::HIP;
   std::vector<const char *> Argv;
   Argv.reserve(5 + 4 + UserArgs.size());
+  Argv.push_back(HipEnabled ? "-xhip" : "-xcuda");
+  Argv.push_back(device ? "--cuda-device-only" : "--cuda-host-only");
 
-  Argv.push_back("-xcuda");
-  if (device)
-    Argv.push_back("--cuda-device-only");
-  else
-    Argv.push_back("--cuda-host-only");
-
-  std::string SDKPathArg = "--cuda-path=";
-  if (!CudaSDKPath.empty()) {
-    SDKPathArg += CudaSDKPath;
+  llvm::StringRef SDKPath = HipEnabled ? RocmSDKPath : CudaSDKPath;
+  std::string SDKPathArg = HipEnabled ? "--rocm-path=" : "--cuda-path=";
+  if (!SDKPath.empty()) {
+    SDKPathArg += SDKPath;
     Argv.push_back(SDKPathArg.c_str());
   }
 
@@ -326,6 +331,12 @@ IncrementalCompilerBuilder::createCuda(bool device) {
     Argv.push_back(ArchArg.c_str());
   }
 
+  if (OffloadCUID.empty())
+    OffloadCUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
+                                  /*LowerCase=*/true);
+  std::string CUIDArg = "-cuid=" + OffloadCUID;
+  Argv.push_back(CUIDArg.c_str());
+
   llvm::append_range(Argv, UserArgs);
 
   std::string TT = TargetTriple ? *TargetTriple : 
llvm::sys::getProcessTriple();
@@ -333,13 +344,13 @@ IncrementalCompilerBuilder::createCuda(bool device) {
 }
 
 llvm::Expected<std::unique_ptr<CompilerInstance>>
-IncrementalCompilerBuilder::CreateCudaDevice() {
-  return IncrementalCompilerBuilder::createCuda(true);
+IncrementalCompilerBuilder::CreateDevice(OffloadType Type) {
+  return IncrementalCompilerBuilder::createOffload(/*device=*/true, Type);
 }
 
 llvm::Expected<std::unique_ptr<CompilerInstance>>
-IncrementalCompilerBuilder::CreateCudaHost() {
-  return IncrementalCompilerBuilder::createCuda(false);
+IncrementalCompilerBuilder::CreateHost(OffloadType Type) {
+  return IncrementalCompilerBuilder::createOffload(/*device=*/false, Type);
 }
 
 Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
diff --git a/clang/test/Interpreter/HIP/hip-not-supported.hip 
b/clang/test/Interpreter/HIP/hip-not-supported.hip
new file mode 100644
index 0000000000000..c66f0fab5bede
--- /dev/null
+++ b/clang/test/Interpreter/HIP/hip-not-supported.hip
@@ -0,0 +1,11 @@
+// Check that clang-repl sets up the HIP environment but reports that HIP
+// offload binary generation is not supported yet. An explicit --offload-arch
+// is passed so the test does not rely on GPU auto-detection. No device code
+// is run, so the architecture is arbitrary.
+// FIXME: Replace this with real HIP execution tests once the HIP device parser
+// can generate offload binaries.
+
+// RUN: cat %s | not clang-repl -hip | FileCheck %s
+
+__attribute__((device)) void f() {}
+// CHECK: HIP offload binary generation is not supported yet.
diff --git a/clang/test/Interpreter/HIP/lit.local.cfg 
b/clang/test/Interpreter/HIP/lit.local.cfg
new file mode 100644
index 0000000000000..cc84168b23713
--- /dev/null
+++ b/clang/test/Interpreter/HIP/lit.local.cfg
@@ -0,0 +1,12 @@
+import ctypes
+
+if "host-supports-jit" not in config.available_features:
+    config.unsupported = True
+elif "amdgpu-registered-target" not in config.available_features:
+    config.unsupported = True
+else:
+    # clang-repl loads the HIP runtime on startup, so it must be available.
+    try:
+        ctypes.CDLL("libamdhip64.so")
+    except OSError:
+        config.unsupported = True
diff --git a/clang/tools/clang-repl/ClangRepl.cpp 
b/clang/tools/clang-repl/ClangRepl.cpp
index c9873540a5d66..7e3d1a7b119de 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -53,6 +53,8 @@ LLVM_ATTRIBUTE_USED int __lsan_is_turned_off() { return 1; }
 #define DEBUG_TYPE "clang-repl"
 
 static llvm::cl::opt<bool> CudaEnabled("cuda", llvm::cl::Hidden);
+static llvm::cl::opt<bool> HipEnabled("hip", llvm::cl::Hidden);
+static llvm::cl::opt<std::string> RocmPath("rocm-path", llvm::cl::Hidden);
 static llvm::cl::opt<std::string> CudaPath("cuda-path", llvm::cl::Hidden);
 static llvm::cl::opt<std::string> OffloadArch("offload-arch", 
llvm::cl::Hidden);
 static llvm::cl::OptionCategory OOPCategory("Out-of-process Execution 
Options");
@@ -310,24 +312,32 @@ int main(int argc, const char **argv) {
   IEB->SlabAllocateSize = *SizeOrErr;
   IEB->UseSharedMemory = UseSharedMemory;
 
-  std::unique_ptr<clang::CompilerInstance> DeviceCI;
-  if (CudaEnabled) {
-    if (!CudaPath.empty())
-      CB.SetCudaSDK(CudaPath);
+  // If both -cuda and -hip are passed, the one that appears later wins.
+  bool UseHip =
+      HipEnabled && (!CudaEnabled || HipEnabled.getPosition() >
+                                         CudaEnabled.getPosition());
+  bool DeviceEnabled = HipEnabled || CudaEnabled;
 
-    if (OffloadArch.empty()) {
-      OffloadArch = "sm_35";
-    }
-    CB.SetOffloadArch(OffloadArch);
+  clang::OffloadType OffloadKind =
+      UseHip ? clang::OffloadType::HIP : clang::OffloadType::CUDA;
+  std::string DevicePath = UseHip ? RocmPath : CudaPath;
+  llvm::StringRef DeviceOffloadArch = !OffloadArch.empty()
+                                          ? llvm::StringRef(OffloadArch)
+                                          : (UseHip ? "native" : "sm_35");
+
+  std::unique_ptr<clang::CompilerInstance> DeviceCI;
 
-    DeviceCI = ExitOnErr(CB.CreateCudaDevice());
+  if (DeviceEnabled) {
+    CB.SetDeviceSDK(OffloadKind, DevicePath);
+    CB.SetOffloadArch(DeviceOffloadArch);
+    DeviceCI = ExitOnErr(CB.CreateDevice(OffloadKind));
   }
 
   // FIXME: Investigate if we could use runToolOnCodeWithArgs from tooling. It
   // can replace the boilerplate code for creation of the compiler instance.
   std::unique_ptr<clang::CompilerInstance> CI;
-  if (CudaEnabled) {
-    CI = ExitOnErr(CB.CreateCudaHost());
+  if (DeviceEnabled) {
+    CI = ExitOnErr(CB.CreateHost(OffloadKind));
   } else {
     CI = ExitOnErr(CB.CreateCpp());
   }
@@ -339,20 +349,21 @@ int main(int argc, const char **argv) {
 
   // Load any requested plugins.
   CI->LoadRequestedPlugins();
-  if (CudaEnabled)
+  if (DeviceEnabled)
     DeviceCI->LoadRequestedPlugins();
 
   std::unique_ptr<clang::Interpreter> Interp;
 
-  if (CudaEnabled) {
-    Interp = ExitOnErr(
-        clang::Interpreter::createWithCUDA(std::move(CI), 
std::move(DeviceCI)));
+  if (DeviceEnabled) {
+    Interp = ExitOnErr(clang::Interpreter::createWithDevice(
+        std::move(CI), std::move(DeviceCI), OffloadKind));
 
-    if (CudaPath.empty()) {
-      ExitOnErr(Interp->LoadDynamicLibrary("libcudart.so"));
+    const char *RuntimeLib = UseHip ? "libamdhip64.so" : "libcudart.so";
+    if (DevicePath.empty()) {
+      ExitOnErr(Interp->LoadDynamicLibrary(RuntimeLib));
     } else {
-      auto CudaRuntimeLibPath = CudaPath + "/lib/libcudart.so";
-      ExitOnErr(Interp->LoadDynamicLibrary(CudaRuntimeLibPath.c_str()));
+      std::string RuntimeLibPath = DevicePath + "/lib/" + RuntimeLib;
+      ExitOnErr(Interp->LoadDynamicLibrary(RuntimeLibPath.c_str()));
     }
   } else {
     Interp =

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

Reply via email to