[clang] [CIR] Cast address spaces in pointer bitcasts (PR #233828)
Arseniy Obolenskiy via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 20 05:57:19 PDT 2026
https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/233828
Casts between function and object pointers failed CIR verification on targets with a separate program address space, like spirv64-intel
>From c84d5fc921f22d26afd6febd5ba97a4f887b93db Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 20 Oct 2026 14:56:08 +0200
Subject: [PATCH] [CIR] Cast address spaces in pointer bitcasts
Casts between function and object pointers failed CIR verification on targets with a separate program address space, like spirv64-intel
---
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 9 ++++-
.../CIR/CodeGen/spirv-intel-fn-ptr-cast.c | 34 +++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 clang/test/CIR/CodeGen/spirv-intel-fn-ptr-cast.c
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index b1c40d9840b7d..179e6202130bd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2657,7 +2657,14 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
mlir::Value src = Visit(const_cast<Expr *>(subExpr));
mlir::Type dstTy = cgf.convertType(destTy);
- assert(!cir::MissingFeatures::addressSpace());
+ // Function and object pointers may differ in address space.
+ auto srcPtrTy = mlir::dyn_cast<cir::PointerType>(src.getType());
+ auto dstPtrTy = mlir::dyn_cast<cir::PointerType>(dstTy);
+ if (srcPtrTy && dstPtrTy &&
+ srcPtrTy.getAddrSpace() != dstPtrTy.getAddrSpace())
+ src = cgf.performAddrSpaceCast(
+ src,
+ builder.getPointerTo(srcPtrTy.getPointee(), dstPtrTy.getAddrSpace()));
if (cgf.sanOpts.has(SanitizerKind::CFIUnrelatedCast))
cgf.getCIRGenModule().errorNYI(subExpr->getSourceRange(),
diff --git a/clang/test/CIR/CodeGen/spirv-intel-fn-ptr-cast.c b/clang/test/CIR/CodeGen/spirv-intel-fn-ptr-cast.c
new file mode 100644
index 0000000000000..d5f6d3d863f80
--- /dev/null
+++ b/clang/test/CIR/CodeGen/spirv-intel-fn-ptr-cast.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple spirv64-intel -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple spirv64-intel -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple spirv64-intel -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+// CIR-LABEL: cir.func{{.*}} @fp_to_void_ptr
+// CIR: %[[FP:.*]] = cir.load{{.*}} : {{.*}}, !cir.ptr<!cir.func<()>, target_address_space(9)>
+// CIR: %[[AS:.*]] = cir.cast address_space %[[FP]] : !cir.ptr<!cir.func<()>, target_address_space(9)> -> !cir.ptr<!cir.func<()>, target_address_space(4)>
+// CIR: cir.cast bitcast %[[AS]] : !cir.ptr<!cir.func<()>, target_address_space(4)> -> !cir.ptr<!void, target_address_space(4)>
+
+// LLVM-LABEL: define{{.*}} ptr addrspace(4) @fp_to_void_ptr
+// LLVM: %[[FP:.*]] = load ptr addrspace(9), ptr addrspace(4)
+// LLVM: addrspacecast ptr addrspace(9) %[[FP]] to ptr addrspace(4)
+
+// OGCG-LABEL: define{{.*}} ptr addrspace(4) @fp_to_void_ptr
+// OGCG: %[[FP:.*]] = load ptr addrspace(9), ptr addrspace(4)
+// OGCG: addrspacecast ptr addrspace(9) %[[FP]] to ptr addrspace(4)
+void *fp_to_void_ptr(void (*fp)(void)) { return (void *)fp; }
+
+// CIR-LABEL: cir.func{{.*}} @void_ptr_to_fp
+// CIR: %[[P:.*]] = cir.load{{.*}} : {{.*}}, !cir.ptr<!void, target_address_space(4)>
+// CIR: %[[AS:.*]] = cir.cast address_space %[[P]] : !cir.ptr<!void, target_address_space(4)> -> !cir.ptr<!void, target_address_space(9)>
+// CIR: cir.cast bitcast %[[AS]] : !cir.ptr<!void, target_address_space(9)> -> !cir.ptr<!cir.func<()>, target_address_space(9)>
+
+// LLVM-LABEL: define{{.*}} ptr addrspace(9) @void_ptr_to_fp
+// LLVM: %[[P:.*]] = load ptr addrspace(4), ptr addrspace(4)
+// LLVM: addrspacecast ptr addrspace(4) %[[P]] to ptr addrspace(9)
+
+// OGCG-LABEL: define{{.*}} ptr addrspace(9) @void_ptr_to_fp
+// OGCG: %[[P:.*]] = load ptr addrspace(4), ptr addrspace(4)
+// OGCG: addrspacecast ptr addrspace(4) %[[P]] to ptr addrspace(9)
+void (*void_ptr_to_fp(void *p))(void) { return (void (*)(void))p; }
More information about the cfe-commits
mailing list