Skip to content

Commit 9e06e8d

Browse files
committed
[CIR] Use cir.get_vptr to initialize vptr members
Previously, following classic codegen, we were using a bitcast to get the address of the vptr member when initializing the vptr in a constructor. This change updates the handling to use cir.get_vptr instead. This is functionally equivalent because the vptr is always at offset zero for the CXXABIs we currently support, but using cir.get_vptr makes what we are doing more explicit.
1 parent aeac352 commit 9e06e8d

File tree

5 files changed

+34
-31
lines changed

5 files changed

+34
-31
lines changed

clang/lib/CIR/CodeGen/CIRGenClass.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -795,24 +795,21 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
795795
}
796796

797797
// Apply the offsets.
798-
Address VTableField = LoadCXXThisAddress();
798+
Address ClassAddr = LoadCXXThisAddress();
799799
if (!NonVirtualOffset.isZero() || VirtualOffset) {
800-
VTableField = ApplyNonVirtualAndVirtualOffset(
801-
loc, *this, VTableField, NonVirtualOffset, VirtualOffset,
800+
ClassAddr = ApplyNonVirtualAndVirtualOffset(
801+
loc, *this, ClassAddr, NonVirtualOffset, VirtualOffset,
802802
Vptr.VTableClass, Vptr.NearestVBase, BaseValueTy);
803803
}
804804

805805
// Finally, store the address point. Use the same CIR types as the field.
806806
//
807807
// vtable field is derived from `this` pointer, therefore they should be in
808808
// the same addr space.
809-
// TODO(cir): We should be using cir.get_vptr rather than a bitcast to get
810-
// the vptr field, but the call to ApplyNonVirtualAndVirtualOffset
811-
// will also need to be adjusted. That should probably be using
812-
// cir.base_class_addr.
813809
assert(!cir::MissingFeatures::addressSpace());
814-
VTableField = builder.createElementBitCast(loc, VTableField,
815-
VTableAddressPoint.getType());
810+
auto VTablePtr = builder.create<cir::VTableGetVPtrOp>(
811+
loc, builder.getPtrToVPtrType(), ClassAddr.getPointer());
812+
Address VTableField = Address(VTablePtr, ClassAddr.getAlignment());
816813
auto storeOp = builder.createStore(loc, VTableAddressPoint, VTableField);
817814
TBAAAccessInfo TBAAInfo =
818815
CGM.getTBAAVTablePtrAccessInfo(VTableAddressPoint.getType());

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,8 @@ mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
992992
VTTPtr = CGF.getBuilder().createVTTAddrPoint(Loc, VTTPtr.getType(), VTTPtr,
993993
VirtualPointerIndex);
994994
// And load the address point from the VTT.
995-
return CGF.getBuilder().createAlignedLoad(Loc, CGF.VoidPtrTy, VTTPtr,
995+
auto VPtrType = cir::VPtrType::get(CGF.getBuilder().getContext());
996+
return CGF.getBuilder().createAlignedLoad(Loc, VPtrType, VTTPtr,
996997
CGF.getPointerAlign());
997998
}
998999

clang/test/CIR/CodeGen/multi-vtable.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int main() {
4040

4141
// CIR: cir.func linkonce_odr @_ZN6MotherC2Ev(%arg0: !cir.ptr<!rec_Mother>
4242
// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV6Mother, address_point = <index = 0, offset = 2>) : !cir.vptr
43-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_Mother>), !cir.ptr<!cir.vptr>
43+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_Mother> -> !cir.ptr<!cir.vptr>
4444
// CIR: cir.store{{.*}} %2, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
4545
// CIR: cir.return
4646
// CIR: }
@@ -53,11 +53,11 @@ int main() {
5353

5454
// CIR: cir.func linkonce_odr @_ZN5ChildC2Ev(%arg0: !cir.ptr<!rec_Child>
5555
// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV5Child, address_point = <index = 0, offset = 2>) : !cir.vptr
56-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_Child>), !cir.ptr<!cir.vptr>
56+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %1 : !cir.ptr<!rec_Child> -> !cir.ptr<!cir.vptr>
5757
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
5858
// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV5Child, address_point = <index = 1, offset = 2>) : !cir.vptr
5959
// CIR: %7 = cir.base_class_addr %1 : !cir.ptr<!rec_Child> nonnull [8] -> !cir.ptr<!rec_Father>
60-
// CIR: %8 = cir.cast(bitcast, %7 : !cir.ptr<!rec_Father>), !cir.ptr<!cir.vptr>
60+
// CIR: %8 = cir.vtable.get_vptr %7 : !cir.ptr<!rec_Father> -> !cir.ptr<!cir.vptr>
6161
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
6262
// CIR: cir.return
6363
// CIR: }

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class B : public A
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]]>) -> ()
4848
// CHECK: %3 = cir.vtable.address_point(@_ZTV1B, address_point = <index = 0, offset = 2>) : !cir.vptr
49-
// CHECK: %4 = cir.cast(bitcast, %1 : !cir.ptr<![[ClassB]]>), !cir.ptr<!cir.vptr>
49+
// CHECK: %4 = cir.vtable.get_vptr %1 : !cir.ptr<!rec_B> -> !cir.ptr<!cir.vptr>
5050
// CHECK: cir.store{{.*}} %3, %4 : !cir.vptr, !cir.ptr<!cir.vptr>
5151
// CHECK: cir.return
5252
// CHECK: }
@@ -74,7 +74,7 @@ class B : public A
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]]>
7676
// CHECK: %2 = cir.vtable.address_point(@_ZTV1A, address_point = <index = 0, offset = 2>) : !cir.vptr
77-
// CHECK: %3 = cir.cast(bitcast, %1 : !cir.ptr<![[ClassA]]>), !cir.ptr<!cir.vptr>
77+
// CHECK: %3 = cir.vtable.get_vptr %1 : !cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr>
7878
// CHECK: cir.store{{.*}} %2, %3 : !cir.vptr, !cir.ptr<!cir.vptr>
7979
// CHECK: cir.return
8080
// CHECK: }

clang/test/CIR/CodeGen/vtt.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ int f() {
3939
// Class A constructor
4040
// CIR: cir.func linkonce_odr @_ZN1AC2Ev(%arg0: !cir.ptr<!rec_A>
4141
// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1A, address_point = <index = 0, offset = 2>) : !cir.vptr
42-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_A>), !cir.ptr<!cir.vptr>
42+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{.*}} : !cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr>
4343
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
4444
// CIR: }
4545

@@ -51,12 +51,14 @@ int f() {
5151
// Class B constructor
5252
// CIR: cir.func linkonce_odr @_ZN1BC2Ev(%arg0: !cir.ptr<!rec_B>
5353
// CIR: %{{[0-9]+}} = cir.vtt.address_point %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, offset = 0 -> !cir.ptr<!cir.ptr<!void>>
54-
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
55-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_B>), !cir.ptr<!cir.ptr<!void>>
56-
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
54+
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.vptr>
55+
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.vptr>, !cir.vptr
56+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_B> -> !cir.ptr<!cir.vptr>
57+
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
5758

5859
// CIR: %{{[0-9]+}} = cir.vtt.address_point %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
59-
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
60+
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.vptr>
61+
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.vptr>, !cir.vptr
6062
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{.*}} : !cir.ptr<!rec_B> -> !cir.ptr<!cir.vptr>
6163
// CIR: %{{[0-9]+}} = cir.load{{.*}} %{{[0-9]+}} : !cir.ptr<!cir.vptr>, !cir.vptr
6264
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.vptr), !cir.ptr<!u8i>
@@ -65,8 +67,8 @@ int f() {
6567
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!u8i>), !cir.ptr<!s64i>
6668
// CIR: %{{[0-9]+}} = cir.load{{.*}} %{{[0-9]+}} : !cir.ptr<!s64i>, !s64i
6769
// CIR: %{{[0-9]+}} = cir.ptr_stride(%{{[0-9]+}} : !cir.ptr<!u8i>, %{{[0-9]+}} : !s64i), !cir.ptr<!u8i>
68-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_B>), !cir.ptr<!cir.ptr<!void>>
69-
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
70+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_B> -> !cir.ptr<!cir.vptr>
71+
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
7072
// CIR: }
7173

7274
// LLVM-LABEL: @_ZN1BC2Ev
@@ -83,12 +85,14 @@ int f() {
8385
// Class C constructor
8486
// CIR: cir.func linkonce_odr @_ZN1CC2Ev(%arg0: !cir.ptr<!rec_C>
8587
// CIR: %{{[0-9]+}} = cir.vtt.address_point %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, offset = 0 -> !cir.ptr<!cir.ptr<!void>>
86-
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
87-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_C>), !cir.ptr<!cir.ptr<!void>>
88-
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
88+
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.vptr>
89+
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.vptr>, !cir.vptr
90+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
91+
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
8992

9093
// CIR: %{{[0-9]+}} = cir.vtt.address_point %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
91-
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
94+
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.vptr>
95+
// CIR: %{{[0-9]+}} = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.vptr>, !cir.vptr
9296
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
9397
// CIR: %{{[0-9]+}} = cir.load{{.*}} %{{[0-9]+}} : !cir.ptr<!cir.vptr>, !cir.vptr
9498
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.vptr), !cir.ptr<!u8i>
@@ -97,8 +101,9 @@ int f() {
97101
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!u8i>), !cir.ptr<!s64i>
98102
// CIR: %{{[0-9]+}} = cir.load{{.*}} %{{[0-9]+}} : !cir.ptr<!s64i>, !s64i
99103
// CIR: %{{[0-9]+}} = cir.ptr_stride(%{{[0-9]+}} : !cir.ptr<!u8i>, %{{[0-9]+}} : !s64i), !cir.ptr<!u8i>
100-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_C>), !cir.ptr<!cir.ptr<!void>>
101-
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
104+
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!u8i>), !cir.ptr<!rec_C>
105+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
106+
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
102107
// CIR: }
103108

104109
// Class D constructor
@@ -118,17 +123,17 @@ int f() {
118123
// CIR: cir.call @_ZN1CC2Ev(%[[C_PTR]], %[[VTT_D_TO_C]]) : (!cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!void>>) -> ()
119124

120125
// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, address_point = <index = 0, offset = 3>) : !cir.vptr
121-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_D>), !cir.ptr<!cir.vptr>
126+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_D> -> !cir.ptr<!cir.vptr>
122127
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
123128
// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, address_point = <index = 2, offset = 3>) : !cir.vptr
124129

125130
// CIR: %{{[0-9]+}} = cir.base_class_addr %{{[0-9]+}} : !cir.ptr<!rec_D> nonnull [40] -> !cir.ptr<!rec_A>
126-
// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_A>), !cir.ptr<!cir.vptr>
131+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr>
127132
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
128133
// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, address_point = <index = 1, offset = 3>) : !cir.vptr
129134

130135
// CIR: cir.base_class_addr %{{[0-9]+}} : !cir.ptr<!rec_D> nonnull [16] -> !cir.ptr<!rec_C>
131-
// CIR: cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr<!rec_C>), !cir.ptr<!cir.vptr>
136+
// CIR: %{{[0-9]+}} = cir.vtable.get_vptr %{{[0-9]+}} : !cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
132137
// CIR: cir.store{{.*}} %{{[0-9]+}}, %{{[0-9]+}} : !cir.vptr, !cir.ptr<!cir.vptr>
133138
// CIR: cir.return
134139
// CIR: }

0 commit comments

Comments
 (0)