diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 68c15fb8a403..0ae6e1c4c5de 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -1407,6 +1407,36 @@ def GlobalAnnotationValuesAttr : CIR_Attr<"GlobalAnnotationValues", let genVerifyDecl = 1; } +//===----------------------------------------------------------------------===// +// AddressPointAttr +//===----------------------------------------------------------------------===// + +def AddressPointAttr : CIR_Attr<"AddressPoint", "address_point"> { + let summary = "Address point attribute"; + + let description = [{ + Attribute specifying the address point within a C++ virtual table (vtable). + + The `index` (vtable index) parameter identifies which vtable to use within a vtable + group, while the `offset` (address point index) specifies the offset within + that vtable where the address begins. + + Example: + ```mlir + cir.global linkonce_odr @_ZTV1B = ... + ... + %3 = cir.vtable.address_point(@_ZTV1B, address_point = )) : !cir.ptr i32>> + ``` + }]; + + let parameters = (ins "int32_t":$index, + "int32_t":$offset); + + let assemblyFormat = [{ + `<` struct($index, $offset) `>` + }]; +} + include "clang/CIR/Dialect/IR/CIRTBAAAttrs.td" include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td" diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index e8a929f7a12e..979041f9c114 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2575,8 +2575,8 @@ def VTableAddrPointOp : CIR_Op<"vtable.address_point", (address point) of a C++ virtual table. An object internal `__vptr` gets initializated on top of the value returned by this operation. - `vtable_index` provides the appropriate vtable within the vtable group - (as specified by Itanium ABI), and `addr_point_index` the actual address + `address_point.index` (vtable index) provides the appropriate vtable within the vtable group + (as specified by Itanium ABI), and `address_point.offset` (address point index) the actual address point within that vtable. The return type is always a `!cir.ptr i32>>`. @@ -2585,14 +2585,13 @@ def VTableAddrPointOp : CIR_Op<"vtable.address_point", ```mlir cir.global linkonce_odr @_ZTV1B = ... ... - %3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr i32>> + %3 = cir.vtable.address_point(@_ZTV1B, address_point = ) : !cir.ptr i32>> ``` }]; let arguments = (ins OptionalAttr:$name, Optional:$sym_addr, - I32Attr:$vtable_index, - I32Attr:$address_point_index); + AddressPointAttr:$address_point); let results = (outs Res:$addr); let assemblyFormat = [{ @@ -2600,8 +2599,7 @@ def VTableAddrPointOp : CIR_Op<"vtable.address_point", ($name^)? ($sym_addr^ `:` type($sym_addr))? `,` - `vtable_index` `=` $vtable_index `,` - `address_point_index` `=` $address_point_index + `address_point` `=` $address_point `)` `:` qualified(type($addr)) attr-dict }]; diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 2e887647ef8a..bb342648a9af 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -950,7 +950,8 @@ CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer( auto VTableSlotPtr = CGF.getBuilder().create( loc, CGF.getBuilder().getPointerTo(TyPtr), ::mlir::FlatSymbolRefAttr{}, VTable, - /*vtable_index=*/0, VTableIndex); + cir::AddressPointAttr::get(CGF.getBuilder().getContext(), 0, + VTableIndex)); VFuncLoad = CGF.getBuilder().createAlignedLoad(loc, TyPtr, VTableSlotPtr, CGF.getPointerAlign()); } @@ -1011,7 +1012,9 @@ CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base, return builder.create( CGM.getLoc(VTableClass->getSourceRange()), vtablePtrTy, mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()), mlir::Value{}, - AddressPoint.VTableIndex, AddressPoint.AddressPointIndex); + cir::AddressPointAttr::get(CGM.getBuilder().getContext(), + AddressPoint.VTableIndex, + AddressPoint.AddressPointIndex)); } mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor( diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareItaniumCXXABI.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareItaniumCXXABI.cpp index bba759494e3b..abd3bcd00d98 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareItaniumCXXABI.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareItaniumCXXABI.cpp @@ -120,7 +120,7 @@ buildDynamicCastToVoidAfterNullCheck(CIRBaseBuilderTy &builder, auto vtablePtr = builder.createLoad(loc, vtablePtrPtr); auto offsetToTopSlotPtr = builder.create( loc, vtablePtrTy, mlir::FlatSymbolRefAttr{}, vtablePtr, - /*vtable_index=*/0, -2ULL); + cir::AddressPointAttr::get(builder.getContext(), 0, -2)); auto offsetToTop = builder.createAlignedLoad(loc, offsetToTopSlotPtr, vtableElemAlign); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index c014bab10d3e..d840c7ea4067 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -3661,13 +3661,15 @@ mlir::LogicalResult CIRToLLVMVTableAddrPointOpLowering::matchAndRewrite( if (!symAddr) { symAddr = getValueForVTableSymbol(op, rewriter, getTypeConverter(), op.getNameAttr(), eltType); - offsets = llvm::SmallVector{0, op.getVtableIndex(), - op.getAddressPointIndex()}; + offsets = llvm::SmallVector{ + 0, op.getAddressPointAttr().getIndex(), + op.getAddressPointAttr().getOffset()}; } else { // Get indirect vtable address point retrieval symAddr = adaptor.getSymAddr(); eltType = converter->convertType(symAddr.getType()); - offsets = llvm::SmallVector{op.getAddressPointIndex()}; + offsets = llvm::SmallVector{ + op.getAddressPointAttr().getOffset()}; } assert(eltType && "Shouldn't ever be missing an eltType here"); diff --git a/clang/test/CIR/CodeGen/derived-to-base.cpp b/clang/test/CIR/CodeGen/derived-to-base.cpp index c6dc92d3ac7b..5ba1dd264cbc 100644 --- a/clang/test/CIR/CodeGen/derived-to-base.cpp +++ b/clang/test/CIR/CodeGen/derived-to-base.cpp @@ -120,7 +120,7 @@ void vcall(C1 &c1) { // CHECK: %6 = cir.load %3 : !cir.ptr, !ty_buffy // CHECK: %7 = cir.cast(bitcast, %4 : !cir.ptr), !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>> // CHECK: %8 = cir.load %7 : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>>, !cir.ptr, !s32i, !ty_buffy) -> !s32i>>> -// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>, vtable_index = 0, address_point_index = 2) : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>> +// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>, address_point = ) : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>> // CHECK: %10 = cir.load align(8) %9 : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>, !cir.ptr, !s32i, !ty_buffy) -> !s32i>> // CHECK: %11 = cir.call %10(%4, %5, %6) : (!cir.ptr, !s32i, !ty_buffy) -> !s32i>>, !cir.ptr, !s32i, !ty_buffy) -> !s32i // CHECK: cir.return diff --git a/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp b/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp index cb962ea437ee..df2533501faf 100644 --- a/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp +++ b/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp @@ -16,7 +16,7 @@ struct Derived final : Base1 {}; Derived *ptr_cast(Base1 *ptr) { return dynamic_cast(ptr); // CHECK: %[[#SRC:]] = cir.load %{{.+}} : !cir.ptr>, !cir.ptr - // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> + // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, address_point = ) : !cir.ptr !u32i>>> // CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr !u32i>>>> // CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr !u32i>>>>, !cir.ptr !u32i>>> // CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr !u32i>>>, !cir.bool @@ -39,7 +39,7 @@ Derived *ptr_cast(Base1 *ptr) { Derived &ref_cast(Base1 &ref) { return dynamic_cast(ref); // CHECK: %[[#SRC:]] = cir.load %{{.+}} : !cir.ptr>, !cir.ptr - // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> + // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, address_point = ) : !cir.ptr !u32i>>> // CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr !u32i>>>> // CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr !u32i>>>>, !cir.ptr !u32i>>> // CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr !u32i>>>, !cir.bool diff --git a/clang/test/CIR/CodeGen/dynamic-cast-relative-layout.cpp b/clang/test/CIR/CodeGen/dynamic-cast-relative-layout.cpp index 27cff8b2d172..c50d03fa68ed 100644 --- a/clang/test/CIR/CodeGen/dynamic-cast-relative-layout.cpp +++ b/clang/test/CIR/CodeGen/dynamic-cast-relative-layout.cpp @@ -21,7 +21,7 @@ void *ptr_cast_to_complete(Base *ptr) { // AFTER-NEXT: %{{.+}} = cir.ternary(%[[#SRC_IS_NOT_NULL]], true { // AFTER-NEXT: %[[#VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr> // AFTER-NEXT: %[[#VPTR:]] = cir.load %[[#VPTR_PTR]] : !cir.ptr>, !cir.ptr -// AFTER-NEXT: %[[#OFFSET_TO_TOP_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr, vtable_index = 0, address_point_index = -2) : !cir.ptr +// AFTER-NEXT: %[[#OFFSET_TO_TOP_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr, address_point = ) : !cir.ptr // AFTER-NEXT: %[[#OFFSET_TO_TOP:]] = cir.load align(4) %[[#OFFSET_TO_TOP_PTR]] : !cir.ptr, !s32i // AFTER-NEXT: %[[#SRC_BYTES_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr // AFTER-NEXT: %[[#DST_BYTES_PTR:]] = cir.ptr_stride(%[[#SRC_BYTES_PTR]] : !cir.ptr, %[[#OFFSET_TO_TOP]] : !s32i), !cir.ptr diff --git a/clang/test/CIR/CodeGen/dynamic-cast.cpp b/clang/test/CIR/CodeGen/dynamic-cast.cpp index 2d1393b4a582..ba3208b907b7 100644 --- a/clang/test/CIR/CodeGen/dynamic-cast.cpp +++ b/clang/test/CIR/CodeGen/dynamic-cast.cpp @@ -73,7 +73,7 @@ void *ptr_cast_to_complete(Base *ptr) { // AFTER-NEXT: %{{.+}} = cir.ternary(%[[#SRC_IS_NOT_NULL]], true { // AFTER-NEXT: %[[#VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr> // AFTER-NEXT: %[[#VPTR:]] = cir.load %[[#VPTR_PTR]] : !cir.ptr>, !cir.ptr -// AFTER-NEXT: %[[#BASE_OFFSET_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr, vtable_index = 0, address_point_index = -2) : !cir.ptr +// AFTER-NEXT: %[[#BASE_OFFSET_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr, address_point = ) : !cir.ptr // AFTER-NEXT: %[[#BASE_OFFSET:]] = cir.load align(8) %[[#BASE_OFFSET_PTR]] : !cir.ptr, !s64i // AFTER-NEXT: %[[#SRC_BYTES_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr // AFTER-NEXT: %[[#DST_BYTES_PTR:]] = cir.ptr_stride(%[[#SRC_BYTES_PTR]] : !cir.ptr, %[[#BASE_OFFSET]] : !s64i), !cir.ptr diff --git a/clang/test/CIR/CodeGen/vtable-rtti.cpp b/clang/test/CIR/CodeGen/vtable-rtti.cpp index 3c8a5253c526..b9857a58b38c 100644 --- a/clang/test/CIR/CodeGen/vtable-rtti.cpp +++ b/clang/test/CIR/CodeGen/vtable-rtti.cpp @@ -45,7 +45,7 @@ class B : public A // CHECK: %1 = cir.load %0 : !cir.ptr>, !cir.ptr // CHECK: %2 = cir.base_class_addr(%1 : !cir.ptr nonnull) [0] -> !cir.ptr // CHECK: cir.call @_ZN1AC2Ev(%2) : (!cir.ptr) -> () -// CHECK: %3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> +// CHECK: %3 = cir.vtable.address_point(@_ZTV1B, address_point = ) : !cir.ptr !u32i>>> // CHECK: %4 = cir.cast(bitcast, %1 : !cir.ptr), !cir.ptr !u32i>>>> // CHECK: cir.store %3, %4 : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CHECK: cir.return @@ -73,7 +73,7 @@ class B : public A // CHECK: %0 = cir.alloca !cir.ptr, !cir.ptr>, ["this", init] {alignment = 8 : i64} // CHECK: cir.store %arg0, %0 : !cir.ptr, !cir.ptr> // CHECK: %1 = cir.load %0 : !cir.ptr>, !cir.ptr -// CHECK: %2 = cir.vtable.address_point(@_ZTV1A, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> +// CHECK: %2 = cir.vtable.address_point(@_ZTV1A, address_point = ) : !cir.ptr !u32i>>> // CHECK: %3 = cir.cast(bitcast, %1 : !cir.ptr), !cir.ptr !u32i>>>> // CHECK: cir.store %2, %3 : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CHECK: cir.return