https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/238495
The result was always in the default address space, so objects in other address spaces left an unrealized_conversion_cast and failed LLVM translation >From 58ad64a3b70880aa5387bceaabc07161cbb2c9f5 Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy <[email protected]> Date: Tue, 3 Nov 2026 19:55:14 +0100 Subject: [PATCH] [CIR] Keep source address space in vtable.get_vptr result The result was always in the default address space, so objects in other address spaces left an unrealized_conversion_cast and failed LLVM translation --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 11 +++++-- .../CIR/Dialect/IR/CIRTypeConstraints.td | 4 +-- clang/lib/CIR/CodeGen/CIRGenClass.cpp | 1 - .../test/CIR/CodeGen/base-class-addrspace.cpp | 32 +++++++++++-------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index bd762aae3e1d7e..b289127db10f77 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3705,7 +3705,14 @@ def CIR_VTableAddrPointOp : CIR_Op<"vtable.address_point", [ // VTableGetVPtr //===----------------------------------------------------------------------===// -def CIR_VTableGetVPtrOp : CIR_Op<"vtable.get_vptr", [Pure]> { +def CIR_VTableGetVPtrOp : CIR_Op<"vtable.get_vptr", [ + Pure, + TypesMatchWith< + "result is a vptr pointer in the address space of 'src'", "src", + "result", + "cir::PointerType::get(cir::VPtrType::get($_self.getContext()), " + "mlir::cast<cir::PointerType>($_self).getAddrSpace())"> +]> { let summary = "Get a the address of the vtable pointer for an object"; let description = [{ The `vtable.get_vptr` operation retrieves the address of the vptr for a @@ -3714,7 +3721,7 @@ def CIR_VTableGetVPtrOp : CIR_Op<"vtable.get_vptr", [Pure]> { The vptr will always be at offset zero in the object, but this operation is more explicit about what is being retrieved than a direct bitcast. - The return type is always `!cir.ptr<!cir.vptr>`. + The return type is `!cir.ptr<!cir.vptr>` in the address space of `src`. Example: ``` diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index a5a33b175ca3a2..b62fc2bac937fe 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -455,9 +455,7 @@ def CIR_AnyDataMemberType : CIR_TypeBase<"::cir::DataMemberType", def CIR_AnyVPtrType : CIR_TypeBase<"::cir::VPtrType", "vptr type">, BuildableType<"$_builder.getType<" # cppType # ">()">; -def CIR_PtrToVPtr : CIR_PtrToType<CIR_AnyVPtrType>, - BuildableType<"$_builder.getType<" # cppType # ">(" - "$_builder.getType<::cir::VPtrType>())">; +def CIR_PtrToVPtr : CIR_PtrToType<CIR_AnyVPtrType>; //===----------------------------------------------------------------------===// // Scalar Type predicates diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 738f5464672435..6bd11b50df058c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -455,7 +455,6 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc, // // vtable field is derived from `this` pointer, therefore they should be in // the same addr space. - assert(!cir::MissingFeatures::addressSpace()); auto vtablePtr = cir::VTableGetVPtrOp::create(builder, loc, classAddr.getPointer()); Address vtableField = Address(vtablePtr, classAddr.getAlignment()); diff --git a/clang/test/CIR/CodeGen/base-class-addrspace.cpp b/clang/test/CIR/CodeGen/base-class-addrspace.cpp index 25126600acabed..a974efd76e4e23 100644 --- a/clang/test/CIR/CodeGen/base-class-addrspace.cpp +++ b/clang/test/CIR/CodeGen/base-class-addrspace.cpp @@ -5,11 +5,6 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG -// FIXME: Add LLVM and OGCG checks for the virtual base once cir.vtable.get_vptr -// keeps the address space. -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -DVBASE %s -o %t-vbase.cir -// RUN: FileCheck --input-file=%t-vbase.cir %s -check-prefix=CIR-VBASE - // A base or derived class subobject is in the address space of the object. #define AS1 __attribute__((address_space(1))) @@ -104,17 +99,26 @@ AS3 D *to_derived_as3(AS3 B *b) { return static_cast<AS3 D *>(b); } // OGCG: %[[DERIVED:.*]] = getelementptr inbounds i8, ptr addrspace(3) %{{.*}}, i64 -4 // OGCG: phi ptr addrspace(3) [ %[[DERIVED]], %{{.*}} ], [ null, %{{.*}} ] -#ifdef VBASE struct V { int v; }; struct W : virtual V { int w; }; AS1 V *to_virtual_base(AS1 W *w) { return w; } -// CIR-VBASE-LABEL: cir.func {{.*}}@_Z15to_virtual_basePU3AS11W -// CIR-VBASE: cir.ternary -// CIR-VBASE: cir.const #cir.ptr<null> : !cir.ptr<!rec_V, target_address_space(1)> -// CIR-VBASE: }, false { -// CIR-VBASE: %[[BYTES:.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!rec_W, target_address_space(1)> -> !cir.ptr<!u8i, target_address_space(1)> -// CIR-VBASE: cir.ptr_stride %[[BYTES]], %{{.*}} : (!cir.ptr<!u8i, target_address_space(1)>, !s64i) -> !cir.ptr<!u8i, target_address_space(1)> -// CIR-VBASE: }) : (!cir.bool) -> !cir.ptr<!rec_V, target_address_space(1)> -#endif +// CIR-LABEL: cir.func {{.*}}@_Z15to_virtual_basePU3AS11W +// CIR: cir.ternary +// CIR: cir.const #cir.ptr<null> : !cir.ptr<!rec_V, target_address_space(1)> +// CIR: }, false { +// CIR: cir.vtable.get_vptr %{{.*}} : !cir.ptr<!rec_W, target_address_space(1)> -> !cir.ptr<!cir.vptr, target_address_space(1)> +// CIR: %[[BYTES:.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!rec_W, target_address_space(1)> -> !cir.ptr<!u8i, target_address_space(1)> +// CIR: cir.ptr_stride %[[BYTES]], %{{.*}} : (!cir.ptr<!u8i, target_address_space(1)>, !s64i) -> !cir.ptr<!u8i, target_address_space(1)> +// CIR: }) : (!cir.bool) -> !cir.ptr<!rec_V, target_address_space(1)> + +// LLVM-LABEL: define {{.*}}@_Z15to_virtual_basePU3AS11W +// LLVM: load ptr, ptr addrspace(1) %[[W:.*]], align 8 +// LLVM: %[[VBASE:.*]] = getelementptr i8, ptr addrspace(1) %[[W]], i64 %{{.*}} +// LLVM: phi ptr addrspace(1) [ %[[VBASE]], %{{.*}} ], [ null, %{{.*}} ] + +// OGCG-LABEL: define {{.*}}@_Z15to_virtual_basePU3AS11W +// OGCG: load ptr, ptr addrspace(1) %[[W:.*]], align 8 +// OGCG: %[[VBASE:.*]] = getelementptr inbounds i8, ptr addrspace(1) %[[W]], i64 %{{.*}} +// OGCG: phi ptr addrspace(1) [ %[[VBASE]], %{{.*}} ], [ null, %{{.*}} ] _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
