Skip to content

Commit 0fd1437

Browse files
el-evLancernmmhaMorris HafnerSharp-Edged
authoredMar 25, 2025
[CIR] Add AddressPointAttr (#1508)
Part of #258 . 1. Added `AddressPointAttr` 2. Change all occurrences of `VTableAddrPointOp` into using the attribute 3. Update tests --------- Co-authored-by: Sirui Mu <msrlancern@gmail.com> Co-authored-by: Morris Hafner <mmha@users.noreply.github.com> Co-authored-by: Morris Hafner <mhafner@nvidia.com> Co-authored-by: Sharp-Edged <48861530+Sharp-Edged@users.noreply.github.com> Co-authored-by: Amr Hesham <amr96@programmer.net> Co-authored-by: Bruno Cardoso Lopes <bruno.cardoso@gmail.com> Co-authored-by: Letu Ren <fantasquex@gmail.com>
1 parent ae826d0 commit 0fd1437

File tree

10 files changed

+53
-20
lines changed

10 files changed

+53
-20
lines changed
 

‎clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

+30
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,36 @@ def GlobalAnnotationValuesAttr : CIR_Attr<"GlobalAnnotationValues",
14071407
let genVerifyDecl = 1;
14081408
}
14091409

1410+
//===----------------------------------------------------------------------===//
1411+
// AddressPointAttr
1412+
//===----------------------------------------------------------------------===//
1413+
1414+
def AddressPointAttr : CIR_Attr<"AddressPoint", "address_point"> {
1415+
let summary = "Address point attribute";
1416+
1417+
let description = [{
1418+
Attribute specifying the address point within a C++ virtual table (vtable).
1419+
1420+
The `index` (vtable index) parameter identifies which vtable to use within a vtable
1421+
group, while the `offset` (address point index) specifies the offset within
1422+
that vtable where the address begins.
1423+
1424+
Example:
1425+
```mlir
1426+
cir.global linkonce_odr @_ZTV1B = ...
1427+
...
1428+
%3 = cir.vtable.address_point(@_ZTV1B, address_point = <index = 0, offset = 2>)) : !cir.ptr<!cir.ptr<() -> i32>>
1429+
```
1430+
}];
1431+
1432+
let parameters = (ins "int32_t":$index,
1433+
"int32_t":$offset);
1434+
1435+
let assemblyFormat = [{
1436+
`<` struct($index, $offset) `>`
1437+
}];
1438+
}
1439+
14101440
include "clang/CIR/Dialect/IR/CIRTBAAAttrs.td"
14111441

14121442
include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td"

‎clang/include/clang/CIR/Dialect/IR/CIROps.td

+5-7
Original file line numberDiff line numberDiff line change
@@ -2575,8 +2575,8 @@ def VTableAddrPointOp : CIR_Op<"vtable.address_point",
25752575
(address point) of a C++ virtual table. An object internal `__vptr`
25762576
gets initializated on top of the value returned by this operation.
25772577

2578-
`vtable_index` provides the appropriate vtable within the vtable group
2579-
(as specified by Itanium ABI), and `addr_point_index` the actual address
2578+
`address_point.index` (vtable index) provides the appropriate vtable within the vtable group
2579+
(as specified by Itanium ABI), and `address_point.offset` (address point index) the actual address
25802580
point within that vtable.
25812581

25822582
The return type is always a `!cir.ptr<!cir.ptr<() -> i32>>`.
@@ -2585,23 +2585,21 @@ def VTableAddrPointOp : CIR_Op<"vtable.address_point",
25852585
```mlir
25862586
cir.global linkonce_odr @_ZTV1B = ...
25872587
...
2588-
%3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<() -> i32>>
2588+
%3 = cir.vtable.address_point(@_ZTV1B, address_point = <index = 0, offset = 2>) : !cir.ptr<!cir.ptr<() -> i32>>
25892589
```
25902590
}];
25912591

25922592
let arguments = (ins OptionalAttr<FlatSymbolRefAttr>:$name,
25932593
Optional<CIR_AnyType>:$sym_addr,
2594-
I32Attr:$vtable_index,
2595-
I32Attr:$address_point_index);
2594+
AddressPointAttr:$address_point);
25962595
let results = (outs Res<CIR_PointerType, "", []>:$addr);
25972596

25982597
let assemblyFormat = [{
25992598
`(`
26002599
($name^)?
26012600
($sym_addr^ `:` type($sym_addr))?
26022601
`,`
2603-
`vtable_index` `=` $vtable_index `,`
2604-
`address_point_index` `=` $address_point_index
2602+
`address_point` `=` $address_point
26052603
`)`
26062604
`:` qualified(type($addr)) attr-dict
26072605
}];

‎clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
950950
auto VTableSlotPtr = CGF.getBuilder().create<cir::VTableAddrPointOp>(
951951
loc, CGF.getBuilder().getPointerTo(TyPtr),
952952
::mlir::FlatSymbolRefAttr{}, VTable,
953-
/*vtable_index=*/0, VTableIndex);
953+
cir::AddressPointAttr::get(CGF.getBuilder().getContext(), 0,
954+
VTableIndex));
954955
VFuncLoad = CGF.getBuilder().createAlignedLoad(loc, TyPtr, VTableSlotPtr,
955956
CGF.getPointerAlign());
956957
}
@@ -1011,7 +1012,9 @@ CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
10111012
return builder.create<cir::VTableAddrPointOp>(
10121013
CGM.getLoc(VTableClass->getSourceRange()), vtablePtrTy,
10131014
mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()), mlir::Value{},
1014-
AddressPoint.VTableIndex, AddressPoint.AddressPointIndex);
1015+
cir::AddressPointAttr::get(CGM.getBuilder().getContext(),
1016+
AddressPoint.VTableIndex,
1017+
AddressPoint.AddressPointIndex));
10151018
}
10161019

10171020
mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(

‎clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareItaniumCXXABI.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ buildDynamicCastToVoidAfterNullCheck(CIRBaseBuilderTy &builder,
120120
auto vtablePtr = builder.createLoad(loc, vtablePtrPtr);
121121
auto offsetToTopSlotPtr = builder.create<cir::VTableAddrPointOp>(
122122
loc, vtablePtrTy, mlir::FlatSymbolRefAttr{}, vtablePtr,
123-
/*vtable_index=*/0, -2ULL);
123+
cir::AddressPointAttr::get(builder.getContext(), 0, -2));
124124
auto offsetToTop =
125125
builder.createAlignedLoad(loc, offsetToTopSlotPtr, vtableElemAlign);
126126

‎clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -3661,13 +3661,15 @@ mlir::LogicalResult CIRToLLVMVTableAddrPointOpLowering::matchAndRewrite(
36613661
if (!symAddr) {
36623662
symAddr = getValueForVTableSymbol(op, rewriter, getTypeConverter(),
36633663
op.getNameAttr(), eltType);
3664-
offsets = llvm::SmallVector<mlir::LLVM::GEPArg>{0, op.getVtableIndex(),
3665-
op.getAddressPointIndex()};
3664+
offsets = llvm::SmallVector<mlir::LLVM::GEPArg>{
3665+
0, op.getAddressPointAttr().getIndex(),
3666+
op.getAddressPointAttr().getOffset()};
36663667
} else {
36673668
// Get indirect vtable address point retrieval
36683669
symAddr = adaptor.getSymAddr();
36693670
eltType = converter->convertType(symAddr.getType());
3670-
offsets = llvm::SmallVector<mlir::LLVM::GEPArg>{op.getAddressPointIndex()};
3671+
offsets = llvm::SmallVector<mlir::LLVM::GEPArg>{
3672+
op.getAddressPointAttr().getOffset()};
36713673
}
36723674

36733675
assert(eltType && "Shouldn't ever be missing an eltType here");

‎clang/test/CIR/CodeGen/derived-to-base.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void vcall(C1 &c1) {
120120
// CHECK: %6 = cir.load %3 : !cir.ptr<!ty_buffy>, !ty_buffy
121121
// CHECK: %7 = cir.cast(bitcast, %4 : !cir.ptr<!ty_C1_>), !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>>
122122
// CHECK: %8 = cir.load %7 : !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>>, !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>
123-
// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>
123+
// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>, address_point = <index = 0, offset = 2>) : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>
124124
// CHECK: %10 = cir.load align(8) %9 : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>, !cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>
125125
// CHECK: %11 = cir.call %10(%4, %5, %6) : (!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>, !cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i
126126
// CHECK: cir.return

‎clang/test/CIR/CodeGen/dynamic-cast-exact.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct Derived final : Base1 {};
1616
Derived *ptr_cast(Base1 *ptr) {
1717
return dynamic_cast<Derived *>(ptr);
1818
// CHECK: %[[#SRC:]] = cir.load %{{.+}} : !cir.ptr<!cir.ptr<!ty_Base1_>>, !cir.ptr<!ty_Base1_>
19-
// CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
19+
// CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, address_point = <index = 0, offset = 2>) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
2020
// CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr<!ty_Base1_>), !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>
2121
// CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>, !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
2222
// CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>, !cir.bool
@@ -39,7 +39,7 @@ Derived *ptr_cast(Base1 *ptr) {
3939
Derived &ref_cast(Base1 &ref) {
4040
return dynamic_cast<Derived &>(ref);
4141
// CHECK: %[[#SRC:]] = cir.load %{{.+}} : !cir.ptr<!cir.ptr<!ty_Base1_>>, !cir.ptr<!ty_Base1_>
42-
// CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
42+
// CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, address_point = <index = 0, offset = 2>) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
4343
// CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr<!ty_Base1_>), !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>
4444
// CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>, !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
4545
// CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>, !cir.bool

‎clang/test/CIR/CodeGen/dynamic-cast-relative-layout.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void *ptr_cast_to_complete(Base *ptr) {
2121
// AFTER-NEXT: %{{.+}} = cir.ternary(%[[#SRC_IS_NOT_NULL]], true {
2222
// AFTER-NEXT: %[[#VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr<!ty_Base>), !cir.ptr<!cir.ptr<!s32i>>
2323
// AFTER-NEXT: %[[#VPTR:]] = cir.load %[[#VPTR_PTR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
24-
// AFTER-NEXT: %[[#OFFSET_TO_TOP_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr<!s32i>, vtable_index = 0, address_point_index = -2) : !cir.ptr<!s32i>
24+
// AFTER-NEXT: %[[#OFFSET_TO_TOP_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr<!s32i>, address_point = <index = 0, offset = -2>) : !cir.ptr<!s32i>
2525
// AFTER-NEXT: %[[#OFFSET_TO_TOP:]] = cir.load align(4) %[[#OFFSET_TO_TOP_PTR]] : !cir.ptr<!s32i>, !s32i
2626
// AFTER-NEXT: %[[#SRC_BYTES_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr<!ty_Base>), !cir.ptr<!u8i>
2727
// AFTER-NEXT: %[[#DST_BYTES_PTR:]] = cir.ptr_stride(%[[#SRC_BYTES_PTR]] : !cir.ptr<!u8i>, %[[#OFFSET_TO_TOP]] : !s32i), !cir.ptr<!u8i>

‎clang/test/CIR/CodeGen/dynamic-cast.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void *ptr_cast_to_complete(Base *ptr) {
7373
// AFTER-NEXT: %{{.+}} = cir.ternary(%[[#SRC_IS_NOT_NULL]], true {
7474
// AFTER-NEXT: %[[#VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr<!ty_Base>), !cir.ptr<!cir.ptr<!s64i>>
7575
// AFTER-NEXT: %[[#VPTR:]] = cir.load %[[#VPTR_PTR]] : !cir.ptr<!cir.ptr<!s64i>>, !cir.ptr<!s64i>
76-
// AFTER-NEXT: %[[#BASE_OFFSET_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr<!s64i>, vtable_index = 0, address_point_index = -2) : !cir.ptr<!s64i>
76+
// AFTER-NEXT: %[[#BASE_OFFSET_PTR:]] = cir.vtable.address_point( %[[#VPTR]] : !cir.ptr<!s64i>, address_point = <index = 0, offset = -2>) : !cir.ptr<!s64i>
7777
// AFTER-NEXT: %[[#BASE_OFFSET:]] = cir.load align(8) %[[#BASE_OFFSET_PTR]] : !cir.ptr<!s64i>, !s64i
7878
// AFTER-NEXT: %[[#SRC_BYTES_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr<!ty_Base>), !cir.ptr<!u8i>
7979
// AFTER-NEXT: %[[#DST_BYTES_PTR:]] = cir.ptr_stride(%[[#SRC_BYTES_PTR]] : !cir.ptr<!u8i>, %[[#BASE_OFFSET]] : !s64i), !cir.ptr<!u8i>

‎clang/test/CIR/CodeGen/vtable-rtti.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class B : public A
4545
// CHECK: %1 = cir.load %0 : !cir.ptr<!cir.ptr<![[ClassB]]>>, !cir.ptr<![[ClassB]]>
4646
// CHECK: %2 = cir.base_class_addr(%1 : !cir.ptr<![[ClassB]]> nonnull) [0] -> !cir.ptr<![[ClassA]]>
4747
// CHECK: cir.call @_ZN1AC2Ev(%2) : (!cir.ptr<![[ClassA]]>) -> ()
48-
// CHECK: %3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
48+
// CHECK: %3 = cir.vtable.address_point(@_ZTV1B, address_point = <index = 0, offset = 2>) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
4949
// CHECK: %4 = cir.cast(bitcast, %1 : !cir.ptr<![[ClassB]]>), !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>
5050
// CHECK: cir.store %3, %4 : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>, !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>
5151
// CHECK: cir.return
@@ -73,7 +73,7 @@ class B : public A
7373
// CHECK: %0 = cir.alloca !cir.ptr<![[ClassA]]>, !cir.ptr<!cir.ptr<![[ClassA]]>>, ["this", init] {alignment = 8 : i64}
7474
// CHECK: cir.store %arg0, %0 : !cir.ptr<![[ClassA]]>, !cir.ptr<!cir.ptr<![[ClassA]]>>
7575
// CHECK: %1 = cir.load %0 : !cir.ptr<!cir.ptr<![[ClassA]]>>, !cir.ptr<![[ClassA]]>
76-
// CHECK: %2 = cir.vtable.address_point(@_ZTV1A, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
76+
// CHECK: %2 = cir.vtable.address_point(@_ZTV1A, address_point = <index = 0, offset = 2>) : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>
7777
// CHECK: %3 = cir.cast(bitcast, %1 : !cir.ptr<![[ClassA]]>), !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>
7878
// CHECK: cir.store %2, %3 : !cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>, !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>>
7979
// CHECK: cir.return

0 commit comments

Comments
 (0)
Failed to load comments.