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 <[email protected]> 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; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
