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

Reply via email to