https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/220982
This adds support for address space lowering for spir/spir64 (not v) which are still widely used in OpenCL testing despite spirv32/spirv64 targets existence. This also corrects alloca address space for all mentioned targets from default to private which is semantically correct for them and avoids emission of spurious address space casts. Assisted-by: claude in test cases updating >From 238609db59e63adedf26c143317fc765d836c325 Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva <[email protected]> Date: Thu, 3 Sep 2026 10:49:40 -0500 Subject: [PATCH] [CIR] Fix address space issues related to SPIR/SPIR-V targets This adds support for address space lowering for spir/spir64 (not v) which are still widely used in OpenCL testing despite spirv32/spirv64 targets existence. This also corrects alloca address space for all mentioned targets from default to private which is semantically correct for them and avoids emission of spurious address space casts. Assisted-by: claude in test cases updating --- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 4 +- clang/lib/CIR/CodeGen/TargetInfo.h | 3 +- clang/lib/CIR/CodeGen/Targets/SPIRV.cpp | 23 +++++++---- .../Transforms/TargetLowering/LowerModule.cpp | 2 + .../address-space-local-var.clcpp | 40 +++++++++---------- .../test/CIR/CodeGenOpenCL/address-spaces.cl | 5 +-- 6 files changed, 42 insertions(+), 35 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 0cb2164f4c0ef..87bb8fbe66585 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -332,10 +332,12 @@ const TargetCIRGenInfo &CIRGenModule::getTargetCIRGenInfo() { theTargetCIRGenInfo = createAMDGPUTargetCIRGenInfo(genTypes); return *theTargetCIRGenInfo; } + case llvm::Triple::spir: + case llvm::Triple::spir64: case llvm::Triple::spirv: case llvm::Triple::spirv32: case llvm::Triple::spirv64: - theTargetCIRGenInfo = createSPIRVTargetCIRGenInfo(genTypes); + theTargetCIRGenInfo = createCommonSPIRTargetCIRGenInfo(genTypes); return *theTargetCIRGenInfo; } } diff --git a/clang/lib/CIR/CodeGen/TargetInfo.h b/clang/lib/CIR/CodeGen/TargetInfo.h index 4f636ab597201..40829f8585268 100644 --- a/clang/lib/CIR/CodeGen/TargetInfo.h +++ b/clang/lib/CIR/CodeGen/TargetInfo.h @@ -198,7 +198,8 @@ createAArch64TargetCIRGenInfo(CIRGenTypes &cgt); std::unique_ptr<TargetCIRGenInfo> createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt); -std::unique_ptr<TargetCIRGenInfo> createSPIRVTargetCIRGenInfo(CIRGenTypes &cgt); +std::unique_ptr<TargetCIRGenInfo> +createCommonSPIRTargetCIRGenInfo(CIRGenTypes &cgt); } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/Targets/SPIRV.cpp b/clang/lib/CIR/CodeGen/Targets/SPIRV.cpp index f2d9810b36061..79ad9857574ca 100644 --- a/clang/lib/CIR/CodeGen/Targets/SPIRV.cpp +++ b/clang/lib/CIR/CodeGen/Targets/SPIRV.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This provides SPIR-V-specific CIR CodeGen logic for function attributes. +// This provides SPIR/SPIRV-specific CIR CodeGen logic for function attributes. // //===----------------------------------------------------------------------===// @@ -22,15 +22,22 @@ using namespace clang::CIRGen; namespace { -class SPIRVABIInfo : public ABIInfo { +class CommonSPIRABIInfo : public ABIInfo { public: - SPIRVABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {} + CommonSPIRABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {} }; -class SPIRVTargetCIRGenInfo : public TargetCIRGenInfo { +class CommonSPIRTargetCIRGenInfo : public TargetCIRGenInfo { public: - SPIRVTargetCIRGenInfo(CIRGenTypes &cgt) - : TargetCIRGenInfo(std::make_unique<SPIRVABIInfo>(cgt)) {} + CommonSPIRTargetCIRGenInfo(CIRGenTypes &cgt) + : TargetCIRGenInfo(std::make_unique<CommonSPIRABIInfo>(cgt)) {} + + mlir::ptr::MemorySpaceAttrInterface + getCIRAllocaAddressSpace() const override { + return cir::LangAddressSpaceAttr::get( + &getABIInfo().cgt.getMLIRContext(), + cir::LangAddressSpace::OffloadPrivate); + } void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global, CIRGenModule &cgm) const override { @@ -57,6 +64,6 @@ class SPIRVTargetCIRGenInfo : public TargetCIRGenInfo { } // namespace std::unique_ptr<TargetCIRGenInfo> -clang::CIRGen::createSPIRVTargetCIRGenInfo(CIRGenTypes &cgt) { - return std::make_unique<SPIRVTargetCIRGenInfo>(cgt); +clang::CIRGen::createCommonSPIRTargetCIRGenInfo(CIRGenTypes &cgt) { + return std::make_unique<CommonSPIRTargetCIRGenInfo>(cgt); } diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index 4061d3b2e58c7..5fd5c8c429f48 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -53,6 +53,8 @@ createTargetLoweringInfo(LowerModule &lm) { case llvm::Triple::nvptx: case llvm::Triple::nvptx64: return createNVPTXTargetLoweringInfo(); + case llvm::Triple::spir: + case llvm::Triple::spir64: case llvm::Triple::spirv: case llvm::Triple::spirv32: case llvm::Triple::spirv64: diff --git a/clang/test/CIR/CodeGenOpenCL/address-space-local-var.clcpp b/clang/test/CIR/CodeGenOpenCL/address-space-local-var.clcpp index bfce737207e87..dcf93a01af038 100644 --- a/clang/test/CIR/CodeGenOpenCL/address-space-local-var.clcpp +++ b/clang/test/CIR/CodeGenOpenCL/address-space-local-var.clcpp @@ -8,28 +8,26 @@ // Test that local variable allocation works correctly in OpenCL C++, // where auto variables have the opencl_private address space. -// CIR: cir.func {{.*}} @k(%arg0: !cir.ptr<!s32i> -// CIR: %[[GP:.*]] = cir.alloca "gp" {{.*}} init : !cir.ptr<!cir.ptr<!s32i>> -// CIR: %[[GR_ALLOCA:.*]] = cir.alloca "gr" {{.*}} init const : !cir.ptr<!cir.ptr<!s32i>> -// CIR: %[[R_ALLOCA:.*]] = cir.alloca "r" {{.*}} init const : !cir.ptr<!cir.ptr<!s32i>> -// CIR: %[[R:.*]] = cir.cast address_space %[[R_ALLOCA]] : !cir.ptr<!cir.ptr<!s32i>> -> !cir.ptr<!cir.ptr<!s32i>> -// CIR: %[[GR:.*]] = cir.cast address_space %[[GR_ALLOCA]] : !cir.ptr<!cir.ptr<!s32i>> -> !cir.ptr<!cir.ptr<!s32i>> -// CIR: cir.store %arg0, %[[GP]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>> -// CIR: %[[DEREF:.*]] = cir.load deref {{.*}} %[[GP]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i> -// CIR: cir.store {{.*}} %[[DEREF]], %[[GR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>> -// CIR: %[[GR_VAL:.*]] = cir.load %[[GR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i> -// CIR: %[[CAST:.*]] = cir.cast address_space %[[GR_VAL]] : !cir.ptr<!s32i> -> !cir.ptr<!s32i> -// CIR: cir.store {{.*}} %[[CAST]], %[[R]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>> +// CIR: cir.func {{.*}} @k(%arg0: !cir.ptr<!s32i, target_address_space(1)> +// CIR: %[[GP:.*]] = cir.alloca "gp" {{.*}} init : !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>> +// CIR: %[[GR:.*]] = cir.alloca "gr" {{.*}} init const : !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>> +// CIR: %[[R:.*]] = cir.alloca "r" {{.*}} init const : !cir.ptr<!cir.ptr<!s32i, target_address_space(4)>> +// CIR: cir.store %arg0, %[[GP]] : !cir.ptr<!s32i, target_address_space(1)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>> +// CIR: %[[DEREF:.*]] = cir.load deref {{.*}} %[[GP]] : !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>, !cir.ptr<!s32i, target_address_space(1)> +// CIR: cir.store {{.*}} %[[DEREF]], %[[GR]] : !cir.ptr<!s32i, target_address_space(1)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>> +// CIR: %[[CAST:.*]] = cir.cast address_space %[[DEREF]] : !cir.ptr<!s32i, target_address_space(1)> -> !cir.ptr<!s32i, target_address_space(4)> +// CIR: cir.store {{.*}} %[[CAST]], %[[R]] : !cir.ptr<!s32i, target_address_space(4)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(4)>> -// LLVM: define dso_local void @k(ptr noundef %[[ARG:.*]]) -// LLVM: %[[GP_ADDR:.*]] = alloca ptr -// LLVM: %[[GR_ADDR:.*]] = alloca ptr -// LLVM: %[[R_ADDR:.*]] = alloca ptr -// LLVM: store ptr %[[ARG]], ptr %[[GP_ADDR]] -// LLVM: %[[V1:.*]] = load ptr, ptr %[[GP_ADDR]] -// LLVM: store ptr %[[V1]], ptr %[[GR_ADDR]] -// LLVM: %[[V2:.*]] = load ptr, ptr %[[GR_ADDR]] -// LLVM: store ptr %[[V2]], ptr %[[R_ADDR]] +// LLVM: define dso_local spir_kernel void @k(ptr addrspace(1) noundef %[[ARG:.*]]) +// LLVM: %[[GP_ADDR:.*]] = alloca ptr addrspace(1) +// LLVM: %[[GR_ADDR:.*]] = alloca ptr addrspace(1) +// LLVM: %[[R_ADDR:.*]] = alloca ptr addrspace(4) +// LLVM: store ptr addrspace(1) %[[ARG]], ptr %[[GP_ADDR]] +// LLVM: %[[V1:.*]] = load ptr addrspace(1), ptr %[[GP_ADDR]] +// LLVM: store ptr addrspace(1) %[[V1]], ptr %[[GR_ADDR]] +// LLVM: %[[V2:.*]] = load ptr addrspace(1), ptr %[[GR_ADDR]] +// LLVM: %[[V3:.*]] = addrspacecast ptr addrspace(1) %[[V2]] to ptr addrspace(4) +// LLVM: store ptr addrspace(4) %[[V3]], ptr %[[R_ADDR]] // OGCG: define dso_local spir_func void @__clang_ocl_kern_imp_k(ptr addrspace(1) noundef align 4 %gp) // OGCG: %gp.addr = alloca ptr addrspace(1) diff --git a/clang/test/CIR/CodeGenOpenCL/address-spaces.cl b/clang/test/CIR/CodeGenOpenCL/address-spaces.cl index fcf1a37ae28b4..217c259b3a24e 100644 --- a/clang/test/CIR/CodeGenOpenCL/address-spaces.cl +++ b/clang/test/CIR/CodeGenOpenCL/address-spaces.cl @@ -34,10 +34,7 @@ void local_pointer_value(global int *ptr) { // CIR-LABEL: cir.func dso_local @local_pointer_value // CIR: %[[SAVED:.*]] = cir.alloca "saved" -// CIR-SAME: !cir.ptr<!cir.ptr<!s32i, lang_address_space(offload_global)>> -// CIR: %[[SAVED_ADDR:.*]] = cir.cast address_space %[[SAVED]] -// CIR-SAME: !cir.ptr<!cir.ptr<!s32i, lang_address_space(offload_global)>> // CIR-SAME: !cir.ptr<!cir.ptr<!s32i, lang_address_space(offload_global)>, lang_address_space(offload_private)> -// CIR: cir.store {{.*}}, %[[SAVED_ADDR]] +// CIR: cir.store {{.*}}, %[[SAVED]] // CIR-SAME: !cir.ptr<!s32i, lang_address_space(offload_global)> // CIR-SAME: !cir.ptr<!cir.ptr<!s32i, lang_address_space(offload_global)>, lang_address_space(offload_private)> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
