From bdf727065b581c45b68a81090272f497f1ce5485 Mon Sep 17 00:00:00 2001
From: wanglei <wanglei@loongson.cn>
Date: Tue, 17 Dec 2024 19:06:10 +0800
Subject: [PATCH] [Offload] Add support for loongarch64 to host plugin

This adds support for the loongarch64 architecture to the offload host
plugin.

Similar to #115773

To fix some test issues, I've had to add the LoongArch64 target to:

- CompilerInvocation::ParseLangArgs
- linkDevice in ClangLinuxWrapper.cpp
- OMPContext::OMPContext (to set the device_kind_cpu trait)

Reviewed By: jhuber6

Pull Request: https://github.com/llvm/llvm-project/pull/120173
---
 clang/lib/Frontend/CompilerInvocation.cpp               | 1 +
 clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp | 1 +
 llvm/lib/Frontend/OpenMP/OMPContext.cpp                 | 1 +
 offload/CMakeLists.txt                                  | 2 ++
 offload/plugins-nextgen/common/src/Utils/ELF.cpp        | 2 ++
 offload/plugins-nextgen/host/CMakeLists.txt             | 6 +++++-
 offload/plugins-nextgen/host/dynamic_ffi/ffi.h          | 2 +-
 offload/plugins-nextgen/host/src/rtl.cpp                | 2 ++
 8 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 23906d5c06d38..298fafc21588a 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4257,6 +4257,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
       if (TT.getArch() == llvm::Triple::UnknownArch ||
           !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||
             TT.getArch() == llvm::Triple::systemz ||
+            TT.getArch() == llvm::Triple::loongarch64 ||
             TT.getArch() == llvm::Triple::nvptx ||
             TT.getArch() == llvm::Triple::nvptx64 ||
             TT.getArch() == llvm::Triple::amdgcn ||
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index fae32a3503c18..4201f043944ed 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -596,6 +596,7 @@ Expected<StringRef> linkDevice(ArrayRef<StringRef> InputFiles,
   case Triple::ppc64:
   case Triple::ppc64le:
   case Triple::systemz:
+  case Triple::loongarch64:
     return generic::clang(InputFiles, Args);
   default:
     return createStringError(Triple.getArchName() +
diff --git a/llvm/lib/Frontend/OpenMP/OMPContext.cpp b/llvm/lib/Frontend/OpenMP/OMPContext.cpp
index ad794d8345cf7..c26f5b49b6008 100644
--- a/llvm/lib/Frontend/OpenMP/OMPContext.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPContext.cpp
@@ -36,6 +36,7 @@ OMPContext::OMPContext(bool IsDeviceCompilation, Triple TargetTriple) {
   case Triple::aarch64:
   case Triple::aarch64_be:
   case Triple::aarch64_32:
+  case Triple::loongarch64:
   case Triple::mips:
   case Triple::mipsel:
   case Triple::mips64:
diff --git a/offload/CMakeLists.txt b/offload/CMakeLists.txt
index 8da95c5c74e44..f6e894d399685 100644
--- a/offload/CMakeLists.txt
+++ b/offload/CMakeLists.txt
@@ -207,6 +207,8 @@ set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} s390x-ibm-linux-gnu")
 set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} s390x-ibm-linux-gnu-LTO")
 set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} riscv64-unknown-linux-gnu")
 set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} riscv64-unknown-linux-gnu-LTO")
+set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} loongarch64-unknown-linux-gnu")
+set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} loongarch64-unknown-linux-gnu-LTO")
 
 # Once the plugins for the different targets are validated, they will be added to
 # the list of supported targets in the current system.
diff --git a/offload/plugins-nextgen/common/src/Utils/ELF.cpp b/offload/plugins-nextgen/common/src/Utils/ELF.cpp
index 10b32440dc877..44d1c737e2efb 100644
--- a/offload/plugins-nextgen/common/src/Utils/ELF.cpp
+++ b/offload/plugins-nextgen/common/src/Utils/ELF.cpp
@@ -47,6 +47,8 @@ uint16_t utils::elf::getTargetMachine() {
   return EM_PPC64;
 #elif defined(__riscv)
   return EM_RISCV;
+#elif defined(__loongarch__)
+  return EM_LOONGARCH;
 #else
 #warning "Unknown ELF compilation target architecture"
   return EM_NONE;
diff --git a/offload/plugins-nextgen/host/CMakeLists.txt b/offload/plugins-nextgen/host/CMakeLists.txt
index cbfe4b951af45..e6b3bdf83d740 100644
--- a/offload/plugins-nextgen/host/CMakeLists.txt
+++ b/offload/plugins-nextgen/host/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(supported_targets x86_64 aarch64 ppc64 ppc64le riscv64 s390x)
+set(supported_targets x86_64 aarch64 ppc64 ppc64le riscv64 s390x loongarch64)
 if(NOT ${CMAKE_SYSTEM_PROCESSOR} IN_LIST supported_targets)
   message(STATUS "Not building ${machine} NextGen offloading plugin")
   return()
@@ -63,4 +63,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64$")
   list(APPEND LIBOMPTARGET_SYSTEM_TARGETS
        "riscv64-unknown-linux-gnu" "riscv64-unknown-linux-gnu-LTO")
   set(LIBOMPTARGET_SYSTEM_TARGETS "${LIBOMPTARGET_SYSTEM_TARGETS}" PARENT_SCOPE)
+elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "loongarch64$")
+  list(APPEND LIBOMPTARGET_SYSTEM_TARGETS
+       "loongarch64-unknown-linux-gnu" "loongarch64-unknown-linux-gnu-LTO")
+  set(LIBOMPTARGET_SYSTEM_TARGETS "${LIBOMPTARGET_SYSTEM_TARGETS}" PARENT_SCOPE)
 endif()
diff --git a/offload/plugins-nextgen/host/dynamic_ffi/ffi.h b/offload/plugins-nextgen/host/dynamic_ffi/ffi.h
index 8b4e0286d65e3..4a9e88cc4dc9c 100644
--- a/offload/plugins-nextgen/host/dynamic_ffi/ffi.h
+++ b/offload/plugins-nextgen/host/dynamic_ffi/ffi.h
@@ -44,7 +44,7 @@ typedef enum ffi_abi {
 #if (defined(_M_X64) || defined(__x86_64__))
   FFI_DEFAULT_ABI = 2, // FFI_UNIX64.
 #elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) ||       \
-    defined(__riscv)
+    defined(__riscv) || defined(__loongarch__)
   FFI_DEFAULT_ABI = 1, // FFI_SYSV.
 #elif defined(__powerpc64__)
   FFI_DEFAULT_ABI = 8, // FFI_LINUX.
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index 915c41e88c582..171c202e3e39e 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -442,6 +442,8 @@ struct GenELF64PluginTy final : public GenericPluginTy {
 #endif
 #elif defined(__riscv) && (__riscv_xlen == 64)
     return llvm::Triple::riscv64;
+#elif defined(__loongarch__) && (__loongarch_grlen == 64)
+    return llvm::Triple::loongarch64;
 #else
     return llvm::Triple::UnknownArch;
 #endif