Author: Chaitanya Date: 2026-04-10T10:43:19+05:30 New Revision: 8401beb49c1ce84ad7314e31d1dde91fe86875ea
URL: https://github.com/llvm/llvm-project/commit/8401beb49c1ce84ad7314e31d1dde91fe86875ea DIFF: https://github.com/llvm/llvm-project/commit/8401beb49c1ce84ad7314e31d1dde91fe86875ea.diff LOG: [CIR][Lowering] Handle address space cast in GlobalViewAttr lowering (#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. Added: clang/test/CIR/Lowering/address-space.cir Modified: clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 2117dd5903ec4..488fc100f981b 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -531,17 +531,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(); @@ -557,7 +561,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()) { @@ -589,13 +594,26 @@ 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) + addrOp = mlir::LLVM::AddrSpaceCastOp::create(rewriter, parentOp->getLoc(), + llvmDstTy, addrOp); + mlir::Type llvmEltTy = convertTypeForMemory(*converter, dataLayout, ptrTy.getPointee()); + // No further cast needed if the pointee type already matches. if (llvmEltTy == sourceType) return addrOp; - mlir::Type llvmDstTy = converter->convertType(globalAttr.getType()); + // With opaque pointers, the pointer type is already correct (either from + // the original AddressOfOp or after an addrspacecast) — skip the + // redundant bitcast. + if (addrOp.getType() == llvmDstTy) + return addrOp; + 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..df203eecdc8e2 --- /dev/null +++ b/clang/test/CIR/Lowering/address-space.cir @@ -0,0 +1,45 @@ +// 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). + // Both the base type (void vs i32) and address space (1 vs 0) diff er. + 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)] + + // Same base type but diff erent address space. + cir.global external target_address_space(1) @counter = #cir.int<42> : !s32i + // LLVM: @counter = addrspace(1) global i32 42 + cir.global external @slot = #cir.const_array<[#cir.global_view<@counter> : !cir.ptr<!s32i>]> : !cir.array<!cir.ptr<!s32i> x 1> + // LLVM: @slot = global [1 x ptr] [ptr addrspacecast (ptr addrspace(1) @counter 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 + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
