Skip to content

[CIR][AMDGPU] Lower Language specific address spaces and implement AMDGPU target - #179084

Merged
RiverDave merged 14 commits into
mainfrom
users/riverdave/langas-lowering-and-amdgpuimpl
Apr 2, 2026
Merged

RiverDave merged 14 commits into
mainfrom
users/riverdave/langas-lowering-and-amdgpuimpl

Conversation

@RiverDave

@RiverDave RiverDave commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Related: #179278, #175871, #160386

Lowering lang address spaces based on support provided in the previous patches. Adds AMDGPUTargetLoweringInfo with the AMDGPU address space mapping.

The langAS → targetAS conversion is structurally inspired by our CXXABILowering. While they serve different purposes, the approach is the same: rewrite all ops that may hold pointer types with an address space qualifier; that's the basic legalization condition.

Since lowerModule was moved out of the LLVM lowering pass, the langAS-to-target transformation now happens during the TargetLowering pass. The resulting TargetAS value is then explicitly lowered in the LowerToLLVM pass,
as the numeric value resides within the attribute. his conversion was not as trivial as I would've preferred, but at the end it serves the purpose of handling the target specific constraint within the specific pass.

@RiverDave
RiverDave marked this pull request as ready for review February 1, 2026 16:12
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:AMDGPU ClangIR Anything related to the ClangIR project labels Feb 1, 2026
@llvmbot

llvmbot commented Feb 1, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-clangir
@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-clang

Author: David Rivera (RiverDave)

Changes

Lowering lang address spaces based on support provided in the previous patches. Adds AMDGPUTargetLoweringInfo with the AMDGPU address space mapping (offload_global→1, offload_local→3, offload_constant→4, offload_private→5, offload_generic→0). The lowering applies to GlobalOp, GetGlobalOp, and pointer types.


Full diff: https://github.com/llvm/llvm-project/pull/179084.diff

10 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+3)
  • (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (+46)
  • (modified) clang/lib/CIR/CodeGen/TargetInfo.h (+3)
  • (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt (+1)
  • (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp (+9-2)
  • (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h (+9)
  • (added) clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp (+47)
  • (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+17-8)
  • (added) clang/test/CIR/CodeGen/amdgpu-address-spaces.cpp (+51)
  • (modified) clang/test/CIR/Lowering/global-address-space.cir (+48-9)
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index c5b4cfc39b6c1..f856407536688 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -244,6 +244,9 @@ const TargetCIRGenInfo &CIRGenModule::getTargetCIRGenInfo() {
       return *theTargetCIRGenInfo;
     }
   }
+  case llvm::Triple::amdgcn: {
+    return *(theTargetCIRGenInfo = createAMDGPUTargetCIRGenInfo(genTypes));
+  }
   }
 }
 
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp
index 50b973591d925..dd34c7e541a21 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp
@@ -54,9 +54,55 @@ class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
   X8664TargetCIRGenInfo(CIRGenTypes &cgt)
       : TargetCIRGenInfo(std::make_unique<X8664ABIInfo>(cgt)) {}
 };
+class AMDGPUABIInfo : public ABIInfo {
+public:
+  AMDGPUABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
+};
+
+class AMDGPUTargetCIRGenInfo : public TargetCIRGenInfo {
+public:
+  AMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
+      : TargetCIRGenInfo(std::make_unique<AMDGPUABIInfo>(cgt)) {}
+
+  clang::LangAS
+  getGlobalVarAddressSpace(CIRGenModule &cgm,
+                           const clang::VarDecl *decl) const override {
+    using clang::LangAS;
+    assert(!cgm.getLangOpts().OpenCL &&
+           !(cgm.getLangOpts().CUDA && cgm.getLangOpts().CUDAIsDevice) &&
+           "Address space agnostic languages only");
+    LangAS defaultGlobalAS = LangAS::opencl_global;
+    if (!decl)
+      return defaultGlobalAS;
+
+    LangAS addrSpace = decl->getType().getAddressSpace();
+    if (addrSpace != LangAS::Default)
+      return addrSpace;
+
+    // Only promote to address space 4 if VarDecl has constant initialization.
+    if (decl->getType().isConstantStorage(cgm.getASTContext(), false, false) &&
+        decl->hasConstantInitialization()) {
+      if (auto constAS = cgm.getTarget().getConstantAddressSpace())
+        return *constAS;
+    }
+
+    return defaultGlobalAS;
+  }
 
+  mlir::ptr::MemorySpaceAttrInterface
+  getCIRAllocaAddressSpace() const override {
+    return cir::LangAddressSpaceAttr::get(
+        &getABIInfo().cgt.getMLIRContext(),
+        cir::LangAddressSpace::OffloadPrivate);
+  }
+};
 } // namespace
 
+std::unique_ptr<TargetCIRGenInfo>
+clang::CIRGen::createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt) {
+  return std::make_unique<AMDGPUTargetCIRGenInfo>(cgt);
+}
+
 std::unique_ptr<TargetCIRGenInfo>
 clang::CIRGen::createX8664TargetCIRGenInfo(CIRGenTypes &cgt) {
   return std::make_unique<X8664TargetCIRGenInfo>(cgt);
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.h b/clang/lib/CIR/CodeGen/TargetInfo.h
index 6108fa456b2c7..752ecb4445b6a 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.h
+++ b/clang/lib/CIR/CodeGen/TargetInfo.h
@@ -130,6 +130,9 @@ class TargetCIRGenInfo {
   }
 };
 
+std::unique_ptr<TargetCIRGenInfo>
+createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt);
+
 std::unique_ptr<TargetCIRGenInfo> createX8664TargetCIRGenInfo(CIRGenTypes &cgt);
 
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
index 92148127424e9..07e3a67f97859 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
@@ -3,6 +3,7 @@ add_clang_library(MLIRCIRTargetLowering
   LowerModule.cpp
   LowerItaniumCXXABI.cpp
   TargetLoweringInfo.cpp
+  Targets/AMDGPU.cpp
 
   DEPENDS
   clangBasic
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp
index e39b764f6a838..844efcb633f94 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp
@@ -46,8 +46,15 @@ static std::unique_ptr<CIRCXXABI> createCXXABI(LowerModule &lm) {
 
 static std::unique_ptr<TargetLoweringInfo>
 createTargetLoweringInfo(LowerModule &lm) {
-  assert(!cir::MissingFeatures::targetLoweringInfo());
-  return std::make_unique<TargetLoweringInfo>();
+  const llvm::Triple &triple = lm.getTarget().getTriple();
+
+  switch (triple.getArch()) {
+  case llvm::Triple::amdgcn:
+    return createAMDGPUTargetLoweringInfo();
+  default:
+    assert(!cir::MissingFeatures::targetLoweringInfo());
+    return std::make_unique<TargetLoweringInfo>();
+  }
 }
 
 LowerModule::LowerModule(clang::LangOptions langOpts,
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h
index 91e7eb79ec83e..80f03283134a9 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_TARGETLOWERINGINFO_H
 
 #include "clang/CIR/Dialect/IR/CIROpsEnums.h"
+#include <memory>
 #include <string>
 
 namespace cir {
@@ -24,8 +25,16 @@ class TargetLoweringInfo {
   virtual ~TargetLoweringInfo();
 
   virtual std::string getLLVMSyncScope(cir::SyncScopeKind syncScope) const;
+
+  virtual unsigned
+  getTargetAddrSpaceFromCIRAddrSpace(cir::LangAddressSpace addrSpace) const {
+    return 0;
+  };
 };
 
+// Target-specific factory functions.
+std::unique_ptr<TargetLoweringInfo> createAMDGPUTargetLoweringInfo();
+
 } // namespace cir
 
 #endif
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp
new file mode 100644
index 0000000000000..058c1200531e5
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp
@@ -0,0 +1,47 @@
+//===- AMDGPU.cpp - Emit CIR for AMDGPU -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../TargetLoweringInfo.h"
+#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace cir {
+
+namespace {
+
+class AMDGPUTargetLoweringInfo : public TargetLoweringInfo {
+public:
+  // Address space mapping from:
+  // https://llvm.org/docs/AMDGPUUsage.html#address-spaces
+  unsigned getTargetAddrSpaceFromCIRAddrSpace(
+      cir::LangAddressSpace addrSpace) const override {
+    switch (addrSpace) {
+    case cir::LangAddressSpace::Default:
+      return 0;
+    case cir::LangAddressSpace::OffloadPrivate:
+      return 5;
+    case cir::LangAddressSpace::OffloadLocal:
+      return 3;
+    case cir::LangAddressSpace::OffloadGlobal:
+      return 1;
+    case cir::LangAddressSpace::OffloadConstant:
+      return 4;
+    case cir::LangAddressSpace::OffloadGeneric:
+      return 0;
+    }
+    llvm_unreachable("Unknown CIR address space for AMDGPU target");
+  }
+};
+
+} // namespace
+
+std::unique_ptr<TargetLoweringInfo> createAMDGPUTargetLoweringInfo() {
+  return std::make_unique<AMDGPUTargetLoweringInfo>();
+}
+
+} // namespace cir
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index c5d6e06b219ce..9adca0fb3e275 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -102,6 +102,13 @@ static mlir::Value createIntCast(mlir::OpBuilder &bld, mlir::Value src,
   return mlir::LLVM::BitcastOp::create(bld, loc, dstTy, src);
 }
 
+static unsigned convertCIRAddrSpaceToTarget(cir::LangAddressSpaceAttr addrSpace,
+                                            cir::LowerModule *lowerModule) {
+  assert(lowerModule && "CIR AS map is not available");
+  return lowerModule->getTargetLoweringInfo()
+      .getTargetAddrSpaceFromCIRAddrSpace(addrSpace.getValue());
+}
+
 static unsigned
 getNumericASFromCIRAS(mlir::ptr::MemorySpaceAttrInterface asAttr,
                       [[maybe_unused]] cir::LowerModule *lowerModule) {
@@ -111,10 +118,11 @@ getNumericASFromCIRAS(mlir::ptr::MemorySpaceAttrInterface asAttr,
           mlir::dyn_cast_if_present<cir::TargetAddressSpaceAttr>(asAttr))
     return targetAddrSpaceAttr.getValue();
 
-  if (mlir::isa_and_present<cir::LangAddressSpaceAttr>(asAttr))
-    llvm_unreachable("lowering LangAddressSpaceAttr NYI");
+  if (auto langAddressSpaceAttr =
+          mlir::dyn_cast<cir::LangAddressSpaceAttr>(asAttr))
+    return convertCIRAddrSpaceToTarget(langAddressSpaceAttr, lowerModule);
 
-  llvm_unreachable("unexpected address Space attribute kindI");
+  llvm_unreachable("unexpected address space attribute kind");
 }
 
 static mlir::LLVM::Visibility
@@ -2973,11 +2981,12 @@ std::unique_ptr<cir::LowerModule> prepareLowerModule(mlir::ModuleOp module) {
 static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
                                  mlir::DataLayout &dataLayout,
                                  cir::LowerModule *lowerModule) {
-  converter.addConversion([&](cir::PointerType type) -> mlir::Type {
-    mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr = type.getAddrSpace();
-    unsigned numericAS = getNumericASFromCIRAS(addrSpaceAttr, lowerModule);
-    return mlir::LLVM::LLVMPointerType::get(type.getContext(), numericAS);
-  });
+  converter.addConversion(
+      [&, lowerModule](cir::PointerType type) -> mlir::Type {
+        mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr = type.getAddrSpace();
+        unsigned numericAS = getNumericASFromCIRAS(addrSpaceAttr, lowerModule);
+        return mlir::LLVM::LLVMPointerType::get(type.getContext(), numericAS);
+      });
   converter.addConversion([&](cir::VPtrType type) -> mlir::Type {
     assert(!cir::MissingFeatures::addressSpace());
     return mlir::LLVM::LLVMPointerType::get(type.getContext());
diff --git a/clang/test/CIR/CodeGen/amdgpu-address-spaces.cpp b/clang/test/CIR/CodeGen/amdgpu-address-spaces.cpp
new file mode 100644
index 0000000000000..35ceed46189dc
--- /dev/null
+++ b/clang/test/CIR/CodeGen/amdgpu-address-spaces.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+// Test address space handling for AMDGPU target in C++ mode (non-OpenCL/HIP).
+// This exercises getGlobalVarAddressSpace.
+
+// Test default address space for globals without explicit AS.
+// For AMDGPU in non-OpenCL/HIP mode, globals default to AS 1 (global).
+int globalVar = 123;
+
+// CIR-DAG: cir.global external lang_address_space(offload_global) @globalVar = #cir.int<123> : !s32i
+// LLVM-DAG: @globalVar = addrspace(1) global i32 123, align 4
+// OGCG-DAG: @globalVar = addrspace(1) global i32 123, align 4
+
+// Test non-const global array goes to global AS.
+int globalArray[4] = {1, 2, 3, 4};
+
+// CIR-DAG: cir.global external lang_address_space(offload_global) @globalArray = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.array<!s32i x 4>
+// LLVM-DAG: @globalArray = addrspace(1) global [4 x i32] [i32 1, i32 2, i32 3, i32 4], align 4
+// OGCG-DAG: @globalArray = addrspace(1) global [4 x i32] [i32 1, i32 2, i32 3, i32 4], align 4
+
+// Test static global goes to global AS.
+static int staticGlobal = 555;
+
+// CIR-DAG: cir.global "private" internal{{.*}}lang_address_space(offload_global) @_ZL12staticGlobal = #cir.int<555> : !s32i
+// LLVM-DAG: @_ZL12staticGlobal = internal addrspace(1) global i32 555, align 4
+// OGCG-DAG: @_ZL12staticGlobal = internal addrspace(1) global i32 555, align 4
+
+// Test constant initialization promotion to AS 4 (constant).
+// Use extern to force emission since const globals are otherwise optimized away.
+extern const int constGlobal = 456;
+
+// CIR-DAG: cir.global constant external target_address_space(4) @constGlobal = #cir.int<456> : !s32i
+// LLVM-DAG: @constGlobal = addrspace(4) constant i32 456, align 4
+// OGCG-DAG: @constGlobal = addrspace(4) constant i32 456, align 4
+
+// Test extern const array goes to constant AS.
+extern const int constArray[3] = {10, 20, 30};
+
+// CIR-DAG: cir.global constant external target_address_space(4) @constArray = #cir.const_array<[#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.int<30> : !s32i]> : !cir.array<!s32i x 3>
+// LLVM-DAG: @constArray = addrspace(4) constant [3 x i32] [i32 10, i32 20, i32 30], align 4
+// OGCG-DAG: @constArray = addrspace(4) constant [3 x i32] [i32 10, i32 20, i32 30], align 4
+
+// Use the static variable to ensure it's emitted.
+int getStaticGlobal() { return staticGlobal; }
diff --git a/clang/test/CIR/Lowering/global-address-space.cir b/clang/test/CIR/Lowering/global-address-space.cir
index c9f25e1126098..7161d6852acb2 100644
--- a/clang/test/CIR/Lowering/global-address-space.cir
+++ b/clang/test/CIR/Lowering/global-address-space.cir
@@ -3,12 +3,13 @@
 
 !s32i = !cir.int<s, 32>
 
-module {
-  cir.global external target_address_space(1) @global_as1 = #cir.int<42> : !s32i
-  // CHECK: llvm.mlir.global external @global_as1(42 : i32) {addr_space = 1 : i32} : i32
+module attributes { cir.triple = "amdgcn-amd-amdhsa" } {
+  // Target address space lowering (passthrough)
+  cir.global external target_address_space(1) @global_target_as1 = #cir.int<42> : !s32i
+  // CHECK: llvm.mlir.global external @global_target_as1(42 : i32) {addr_space = 1 : i32} : i32
 
-  cir.global external target_address_space(3) @global_as3 = #cir.int<100> : !s32i
-  // CHECK: llvm.mlir.global external @global_as3(100 : i32) {addr_space = 3 : i32} : i32
+  cir.global external target_address_space(3) @global_target_as3 = #cir.int<100> : !s32i
+  // CHECK: llvm.mlir.global external @global_target_as3(100 : i32) {addr_space = 3 : i32} : i32
 
   cir.global external @global_default = #cir.int<0> : !s32i
   // CHECK: llvm.mlir.global external @global_default(0 : i32) {addr_space = 0 : i32} : i32
@@ -16,20 +17,20 @@ module {
   // Test cir.get_global with address space produces correct llvm.mlir.addressof type
   // CHECK-LABEL: llvm.func @test_get_global_as1
   cir.func @test_get_global_as1() -> !s32i {
-    // CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @global_as1 : !llvm.ptr<1>
+    // CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @global_target_as1 : !llvm.ptr<1>
     // CHECK: %[[VAL:.*]] = llvm.load %[[ADDR]] {{.*}} : !llvm.ptr<1> -> i32
     // CHECK: llvm.return %[[VAL]] : i32
-    %0 = cir.get_global @global_as1 : !cir.ptr<!s32i, target_address_space(1)>
+    %0 = cir.get_global @global_target_as1 : !cir.ptr<!s32i, target_address_space(1)>
     %1 = cir.load %0 : !cir.ptr<!s32i, target_address_space(1)>, !s32i
     cir.return %1 : !s32i
   }
 
   // CHECK-LABEL: llvm.func @test_get_global_as3
   cir.func @test_get_global_as3() -> !s32i {
-    // CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @global_as3 : !llvm.ptr<3>
+    // CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @global_target_as3 : !llvm.ptr<3>
     // CHECK: %[[VAL:.*]] = llvm.load %[[ADDR]] {{.*}} : !llvm.ptr<3> -> i32
     // CHECK: llvm.return %[[VAL]] : i32
-    %0 = cir.get_global @global_as3 : !cir.ptr<!s32i, target_address_space(3)>
+    %0 = cir.get_global @global_target_as3 : !cir.ptr<!s32i, target_address_space(3)>
     %1 = cir.load %0 : !cir.ptr<!s32i, target_address_space(3)>, !s32i
     cir.return %1 : !s32i
   }
@@ -43,4 +44,42 @@ module {
     %1 = cir.load %0 : !cir.ptr<!s32i>, !s32i
     cir.return %1 : !s32i
   }
+
+  // Language address space lowering (AMDGPU mapping)
+  // See: https://llvm.org/docs/AMDGPUUsage.html#address-spaces
+  // OffloadGlobal -> 1
+  cir.global external lang_address_space(offload_global) @global_lang_global = #cir.int<1> : !s32i
+  // CHECK: llvm.mlir.global external @global_lang_global(1 : i32) {addr_space = 1 : i32} : i32
+
+  // OffloadLocal -> 3
+  cir.global "private" internal lang_address_space(offload_local) @global_lang_local : !s32i
+  // CHECK: llvm.mlir.global internal @global_lang_local() {addr_space = 3 : i32} : i32
+
+  // OffloadConstant -> 4
+  cir.global external lang_address_space(offload_constant) @global_lang_constant = #cir.int<2> : !s32i
+  // CHECK: llvm.mlir.global external @global_lang_constant(2 : i32) {addr_space = 4 : i32} : i32
+
+  // OffloadPrivate -> 5
+  cir.global "private" internal lang_address_space(offload_private) @global_lang_private : !s32i
+  // CHECK: llvm.mlir.global internal @global_lang_private() {addr_space = 5 : i32} : i32
+
+  // OffloadGeneric -> 0
+  cir.global external lang_address_space(offload_generic) @global_lang_generic = #cir.int<3> : !s32i
+  // CHECK: llvm.mlir.global external @global_lang_generic(3 : i32) {addr_space = 0 : i32} : i32
+
+  // Pointer type lowering with lang_address_space
+  // CHECK: llvm.func @test_ptr_lang_as(%arg0: !llvm.ptr<1>)
+  cir.func @test_ptr_lang_as(%arg0: !cir.ptr<!s32i, lang_address_space(offload_global)>) {
+    // The alloca stores a pointer to address space 1, but the alloca itself is on the stack (default AS)
+    // CHECK: llvm.alloca {{.*}} x !llvm.ptr<1> {{.*}} : (i64) -> !llvm.ptr
+    %0 = cir.alloca !cir.ptr<!s32i, lang_address_space(offload_global)>, !cir.ptr<!cir.ptr<!s32i, lang_address_space(offload_global)>>, ["arg", init] {alignment = 8 : i64}
+    cir.return
+  }
+
+  // CHECK: llvm.func @test_ptr_target_as(%arg0: !llvm.ptr<5>)
+  cir.func @test_ptr_target_as(%arg0: !cir.ptr<!s32i, target_address_space(5)>) {
+    // CHECK: llvm.alloca {{.*}} x !llvm.ptr<5> {{.*}} : (i64) -> !llvm.ptr
+    %0 = cir.alloca !cir.ptr<!s32i, target_address_space(5)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(5)>>, ["arg", init] {alignment = 8 : i64}
+    cir.return
+  }
 }

@RiverDave
RiverDave requested a review from koparasy February 1, 2026 16:15
Comment thread clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp Outdated
Comment thread clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp
@RiverDave
RiverDave force-pushed the users/riverdave/langas-lowering-and-amdgpuimpl branch from a51d3a2 to ea88636 Compare February 4, 2026 20:10
@RiverDave
RiverDave force-pushed the users/riverdave/as-for-globalops branch from d6d3754 to 4d76edd Compare February 4, 2026 20:10
@RiverDave
RiverDave force-pushed the users/riverdave/langas-lowering-and-amdgpuimpl branch from ea88636 to d086dbf Compare February 4, 2026 20:25
@RiverDave
RiverDave force-pushed the users/riverdave/as-for-globalops branch from 4d76edd to 6121b91 Compare February 4, 2026 20:25
@RiverDave
RiverDave force-pushed the users/riverdave/as-for-globalops branch from 6121b91 to 9e991a1 Compare February 26, 2026 22:23
@RiverDave

RiverDave commented Feb 27, 2026

Copy link
Copy Markdown
Contributor Author

Note: This is not abandoned, I'm focusing on merging the upstack PR's and rewriting the lowering of (LangAS -> TargetAS) given that we moved lowerModule to TargetLowering pass. Thank you for your patience 🙂

@RiverDave
RiverDave force-pushed the users/riverdave/as-for-globalops branch 2 times, most recently from 116805a to b89c142 Compare March 2, 2026 21:33
@RiverDave
RiverDave force-pushed the users/riverdave/langas-lowering-and-amdgpuimpl branch from d086dbf to 0f75953 Compare March 12, 2026 20:43
@github-actions

github-actions Bot commented Mar 12, 2026

Copy link
Copy Markdown

✅ With the latest revision this PR passed the C/C++ code formatter.

@github-actions

github-actions Bot commented Mar 12, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 116471 tests passed
  • 3934 tests skipped

✅ The build succeeded and all tests passed.

@RiverDave
RiverDave force-pushed the users/riverdave/langas-lowering-and-amdgpuimpl branch from 0f75953 to a8c797b Compare March 13, 2026 08:59
@RiverDave

RiverDave commented Mar 13, 2026

Copy link
Copy Markdown
Contributor Author

This has gotten updated - some key things:

  • The current design on the langAS -> TargetAS conversion is currently inspired by our CXXABILowering. They serve different purposes but the intention/structure remained the same. We need to rewrite all ops that may hold pointer types with an AS qualifier, that's our basic legalization condition.

This branch is fairly outdated (I think CI might be failing due to that) so I'll rebase it when #179082 lands.

cc @andykaylor

@RiverDave
RiverDave force-pushed the users/riverdave/langas-lowering-and-amdgpuimpl branch from 0d2b860 to bdf36bc Compare March 20, 2026 20:25
@RiverDave

Copy link
Copy Markdown
Contributor Author

Gentle ping: @andykaylor @bcardosolopes

@jsjodin
jsjodin requested a review from arsenm April 1, 2026 14:30

@bcardosolopes bcardosolopes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@RiverDave
RiverDave force-pushed the users/riverdave/langas-lowering-and-amdgpuimpl branch from 9ee437b to 5e53353 Compare April 2, 2026 05:02
@skc7

skc7 commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

This PR is pre-requisite for amdgpu builtins codegen upstreaming.
Thanks for working on this @RiverDave

@RiverDave

Copy link
Copy Markdown
Contributor Author

This PR is pre-requisite for amdgpu builtins codegen upstreaming. Thanks for working on this @RiverDave

Yes, I'll merge once ci's pass given I finally got the approval I wanted :D

@RiverDave
RiverDave force-pushed the users/riverdave/langas-lowering-and-amdgpuimpl branch from 5e53353 to 22e003d Compare April 2, 2026 06:13
@RiverDave
RiverDave merged commit e3cbd99 into main Apr 2, 2026
10 checks passed
@RiverDave
RiverDave deleted the users/riverdave/langas-lowering-and-amdgpuimpl branch April 2, 2026 07:00
@llvm-ci

llvm-ci commented Apr 2, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder openmp-s390x-linux running on systemz-1 while building clang at step 6 "test-openmp".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/88/builds/22014

Here is the relevant piece of the build log for the reference
Step 6 (test-openmp) failure: test (failure)
******************** TEST 'libomp :: tasking/issue-94260-2.c' FAILED ********************
Exit Code: -11

Command Output (stdout):
--
# RUN: at line 1
/home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/./bin/clang -fopenmp   -I /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -I /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.src/openmp/runtime/test -L /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/src  -fno-omit-frame-pointer -mbackchain -I /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.src/openmp/runtime/test/ompt /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.src/openmp/runtime/test/tasking/issue-94260-2.c -o /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp -lm -latomic && /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp
# executed command: /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/./bin/clang -fopenmp -I /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -I /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.src/openmp/runtime/test -L /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -fno-omit-frame-pointer -mbackchain -I /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.src/openmp/runtime/test/ompt /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.src/openmp/runtime/test/tasking/issue-94260-2.c -o /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp -lm -latomic
# executed command: /home/uweigand/sandbox/buildbot/openmp-s390x-linux/llvm.build/runtimes/runtimes-bins/openmp/runtime/test/tasking/Output/issue-94260-2.c.tmp
# note: command had no output on stdout or stderr
# error: command failed with exit status: -11

--

********************


ZakyHermawan added a commit to ZakyHermawan/llvm-project that referenced this pull request Apr 2, 2026
Signed-off-by: ZakyHermawan <zaky.hermawan9615@gmail.com>
@llvm-ci

llvm-ci commented Apr 5, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder clang-ppc64le-linux-test-suite running on ppc64le-clang-test-suite while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/95/builds/20539

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: 1200 seconds without output running [b'ninja', b'check-all'], attempting to kill
...
105.475 [2/1/84] Generating ASAN_INST_TEST_OBJECTS.gtest-all.cc.powerpc64le-inline.o
106.744 [0/2/85] Generating POWERPC64LELinuxDynamicConfig/Asan-powerpc64le-inline-Dynamic-Test
107.402 [0/1/86] Generating POWERPC64LELinuxConfig/Asan-powerpc64le-inline-Test
153.399 [3/5/1346] Linking CXX executable tools/clang/unittests/Interpreter/ExceptionTests/ClangReplInterpreterExceptionTests
165.183 [2/4/1347] No install step for 'runtimes'
165.289 [1/4/1349] Completed 'runtimes'
187.507 [1/3/1350] Linking CXX executable tools/clang/unittests/Interpreter/ClangReplInterpreterTests
222.560 [1/2/1351] Linking CXX executable tools/clang/tools/extra/clangd/unittests/ClangdTests
242.683 [1/1/1352] Linking CXX executable tools/clang/unittests/AllClangUnitTests
242.686 [0/1/1352] Running all regression tests
command timed out: 1200 seconds without output running [b'ninja', b'check-all'], attempting to kill
process killed by signal 9
program finished with exit code -1
elapsedTime=1443.666039

zwu-2025 pushed a commit to zwu-2025/llvm-project that referenced this pull request May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:AMDGPU clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants