[clang] [CIR][Lowering] Handle address space cast in GlobalViewAttr lowering (PR #190197)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 2 08:39:25 PDT 2026
https://github.com/skc7 created https://github.com/llvm/llvm-project/pull/190197
Upstreaming clangIR PR: https://github.com/llvm/clangir/pull/2099
This PR fixes the GlobalViewAttr LLVM lowering to use AddrSpaceCastOp when the source and destination address spaces differ.
This fixes crashes when lowering globals referenced across address spaces, such as AMDGPU globals in addrspace(1) referenced from llvm.compiler.used arrays.
>From 7b8f913dd774ad361364c9ff14ff1eba74899936 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Thu, 2 Apr 2026 21:04:14 +0530
Subject: [PATCH] [CIR][Lowering] Handle address space cast in GlobalViewAttr
lowering
---
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 18 +++++++--
clang/test/CIR/Lowering/address-space.cir | 38 +++++++++++++++++++
2 files changed, 53 insertions(+), 3 deletions(-)
create mode 100644 clang/test/CIR/Lowering/address-space.cir
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index b622fa1ef3205..42e250f533ef2 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -674,17 +674,21 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
auto moduleOp = parentOp->getParentOfType<mlir::ModuleOp>();
mlir::DataLayout dataLayout(moduleOp);
mlir::Type sourceType;
- assert(!cir::MissingFeatures::addressSpace());
+ unsigned sourceAddrSpace = 0;
llvm::StringRef symName;
mlir::Operation *sourceSymbol =
mlir::SymbolTable::lookupSymbolIn(moduleOp, globalAttr.getSymbol());
if (auto llvmSymbol = dyn_cast<mlir::LLVM::GlobalOp>(sourceSymbol)) {
sourceType = llvmSymbol.getType();
symName = llvmSymbol.getSymName();
+ sourceAddrSpace = llvmSymbol.getAddrSpace();
} else if (auto cirSymbol = dyn_cast<cir::GlobalOp>(sourceSymbol)) {
sourceType =
convertTypeForMemory(*converter, dataLayout, cirSymbol.getSymType());
symName = cirSymbol.getSymName();
+ if (auto targetAS = mlir::dyn_cast_if_present<cir::TargetAddressSpaceAttr>(
+ cirSymbol.getAddrSpaceAttr()))
+ sourceAddrSpace = targetAS.getValue();
} else if (auto llvmFun = dyn_cast<mlir::LLVM::LLVMFuncOp>(sourceSymbol)) {
sourceType = llvmFun.getFunctionType();
symName = llvmFun.getSymName();
@@ -700,7 +704,8 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
mlir::Location loc = parentOp->getLoc();
mlir::Value addrOp = mlir::LLVM::AddressOfOp::create(
- rewriter, loc, mlir::LLVM::LLVMPointerType::get(rewriter.getContext()),
+ rewriter, loc,
+ mlir::LLVM::LLVMPointerType::get(rewriter.getContext(), sourceAddrSpace),
symName);
if (globalAttr.getIndices()) {
@@ -732,13 +737,20 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
}
if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(globalAttr.getType())) {
+ auto llvmDstTy = converter->convertType<mlir::LLVM::LLVMPointerType>(ptrTy);
+ unsigned dstAddrSpace = llvmDstTy.getAddressSpace();
+
+ if (sourceAddrSpace != dstAddrSpace) {
+ return mlir::LLVM::AddrSpaceCastOp::create(rewriter, parentOp->getLoc(),
+ llvmDstTy, addrOp);
+ }
+
mlir::Type llvmEltTy =
convertTypeForMemory(*converter, dataLayout, ptrTy.getPointee());
if (llvmEltTy == sourceType)
return addrOp;
- mlir::Type llvmDstTy = converter->convertType(globalAttr.getType());
return mlir::LLVM::BitcastOp::create(rewriter, parentOp->getLoc(),
llvmDstTy, addrOp);
}
diff --git a/clang/test/CIR/Lowering/address-space.cir b/clang/test/CIR/Lowering/address-space.cir
new file mode 100644
index 0000000000000..b2c9a9792b882
--- /dev/null
+++ b/clang/test/CIR/Lowering/address-space.cir
@@ -0,0 +1,38 @@
+// RUN: cir-translate %s -cir-to-llvmir --target spirv64-unknown-unknown -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+!s32i = !cir.int<s, 32>
+
+module {
+ cir.global external target_address_space(7) @addrspace3 = #cir.int<3> : !s32i
+ // LLVM: @addrspace3 = addrspace(7) global i32
+
+ // Test GlobalViewAttr with address space cast.
+ cir.global external target_address_space(1) @global_in_as1 = #cir.int<42> : !s32i
+ // LLVM: @global_in_as1 = addrspace(1) global i32 42
+
+ // Reference to @global_in_as1 with a pointer in default address space (0).
+ cir.global external @ref_with_addrspacecast = #cir.const_array<[#cir.global_view<@global_in_as1> : !cir.ptr<!cir.void>]> : !cir.array<!cir.ptr<!cir.void> x 1>
+ // LLVM: @ref_with_addrspacecast = global [1 x ptr] [ptr addrspacecast (ptr addrspace(1) @global_in_as1 to ptr)]
+
+ // LLVM: define void @foo(ptr %0)
+ cir.func @foo(%arg0: !cir.ptr<!s32i>) {
+ // LLVM-NEXT: alloca ptr,
+ %0 = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arg", init] {alignment = 8 : i64}
+ cir.return
+ }
+
+ // LLVM: define void @bar(ptr addrspace(1) %0)
+ cir.func @bar(%arg0: !cir.ptr<!s32i, target_address_space(1)>) {
+ // LLVM-NEXT: alloca ptr addrspace(1)
+ %0 = cir.alloca !cir.ptr<!s32i, target_address_space(1)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>, ["arg", init] {alignment = 8 : i64}
+ cir.return
+ }
+
+ // LLVM: define void @baz(ptr %0)
+ cir.func @baz(%arg0: !cir.ptr<!s32i, target_address_space(0)>) {
+ // LLVM-NEXT: alloca ptr,
+ %0 = cir.alloca !cir.ptr<!s32i, target_address_space(0)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(0)>>, ["arg", init] {alignment = 8 : i64}
+ cir.return
+ }
+}
More information about the cfe-commits
mailing list