https://github.com/koparasy created
https://github.com/llvm/llvm-project/pull/237438
CodeGenTypes::ConvertType lowered every ObjCObjectPointerType to a pointer in
address space 0, ignoring the target address space of the pointee. Other
pointers use getTargetAddressSpace() on the pointee.
On targets where LangAS::Default maps to address space 0. All targets that
properly support Objective-C have as Default address space the value 0. Thus
this does not return any errors.
On SPIR-V targets whose default address space is generic (e.g. spirv64-intel),
it made `id` a private pointer while `void *` was a generic one, so converting
between them emitted a generic-to-private addrspacecast. I observed this
behavior while creating #224699 .
This PR fixes the AS issue. However, it does not mean that ObjC properly works
on SPIR-V targets. That is outside of the scope. I thought it will keep PR
history clean if I separate this from #224699
>From 36326a88b07215c475a09b35d22eeb68a47f1fe1 Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <[email protected]>
Date: Fri, 30 Oct 2026 16:47:15 -0700
Subject: [PATCH] [clang][CodeGen] Lower ObjC object pointers in the pointee's
address space
CodeGenTypes::ConvertType lowered every ObjCObjectPointerType to a
pointer in address space 0, ignoring the target address space of the
pointee. Other pointers use getTargetAddressSpace() on the pointee.
On targets where LangAS::Default maps to address space 0. All targets
that properly support Objective-C have as Default address space the value
0. Thus this does not return any errors.
On SPIR-V targets whose default address space is generic (e.g.
spirv64-intel), it made `id` a private pointer while `void *` was a
generic one, so converting between them emitted a generic-to-private
addrspacecast. I observed this behavior while creating #224699 .
This PR fixes the AS issue. However, it does not mean that ObjC properly
works on SPIR-V targets. That is outside of the scope. I thought it will
keep PR history clean if I separate this from #224699 .
---
clang/lib/CodeGen/CodeGenTypes.cpp | 7 +++--
.../spirv-object-pointer-addrspace.m | 29 +++++++++++++++++++
2 files changed, 34 insertions(+), 2 deletions(-)
create mode 100644 clang/test/CodeGenObjC/spirv-object-pointer-addrspace.m
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp
b/clang/lib/CodeGen/CodeGenTypes.cpp
index daed8559cc62f5..272b686506b853 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -723,9 +723,12 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
break;
}
- case Type::ObjCObjectPointer:
- ResultType = llvm::PointerType::getUnqual(getLLVMContext());
+ case Type::ObjCObjectPointer: {
+ QualType ETy = cast<ObjCObjectPointerType>(Ty)->getPointeeType();
+ unsigned AS = getTargetAddressSpace(ETy);
+ ResultType = llvm::PointerType::get(getLLVMContext(), AS);
break;
+ }
case Type::Enum: {
const auto *ED = Ty->castAsEnumDecl();
diff --git a/clang/test/CodeGenObjC/spirv-object-pointer-addrspace.m
b/clang/test/CodeGenObjC/spirv-object-pointer-addrspace.m
new file mode 100644
index 00000000000000..826132e896a2f9
--- /dev/null
+++ b/clang/test/CodeGenObjC/spirv-object-pointer-addrspace.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple spirv64 -fobjc-runtime=gnustep-2.0 -emit-llvm -o -
%s | FileCheck %s --check-prefixes=CHECK,PRIV
+// RUN: %clang_cc1 -triple spirv64-intel -fobjc-runtime=gnustep-2.0 -emit-llvm
-o - %s | FileCheck %s --check-prefixes=CHECK,GEN
+
+// Objective-C object pointers are lowered in the target address space of the
+// default address space, like other pointers. On spirv64-intel that is the
+// generic address space, so converting between id and void * needs no cast.
+
+@interface Foo
+@end
+
+// PRIV: @glob = global ptr null
+// GEN: @glob = addrspace(1) global ptr addrspace(4) null
+id glob;
+
+// PRIV: define spir_func ptr @to_void(ptr noundef %x)
+// GEN: define spir_func ptr addrspace(4) @to_void(ptr addrspace(4) noundef
%x)
+// CHECK: [[V:%.*]] = load
+// CHECK-NEXT: ret {{.*}} [[V]]
+void *to_void(id x) { return (void *)x; }
+
+// PRIV: define spir_func ptr @from_void(ptr noundef %p)
+// GEN: define spir_func ptr addrspace(4) @from_void(ptr addrspace(4) noundef
%p)
+// CHECK: [[V:%.*]] = load
+// CHECK-NEXT: ret {{.*}} [[V]]
+id from_void(void *p) { return (id)p; }
+
+// PRIV: define spir_func ptr @to_foo(ptr noundef %x)
+// GEN: define spir_func ptr addrspace(4) @to_foo(ptr addrspace(4) noundef %x)
+Foo *to_foo(id x) { return x; }
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits