forked from OSchip/llvm-project
Cast vtable address points to i32 (...)** to enable more globalopt
We currently use i32 (...)** as the type of the vptr field in the LLVM struct type. LLVM's GlobalOpt prefers any bitcasts to be on the side of the data being stored rather than on the pointer being stored to. Reviewers: majnemer Differential Revision: http://reviews.llvm.org/D5916 llvm-svn: 223267
This commit is contained in:
parent
1780d82f35
commit
8d58513da4
|
@ -1982,10 +1982,14 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,
|
|||
NonVirtualOffset,
|
||||
VirtualOffset);
|
||||
|
||||
// Finally, store the address point.
|
||||
llvm::Type *AddressPointPtrTy =
|
||||
VTableAddressPoint->getType()->getPointerTo();
|
||||
VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy);
|
||||
// Finally, store the address point. Use the same LLVM types as the field to
|
||||
// support optimization.
|
||||
llvm::Type *VTablePtrTy =
|
||||
llvm::FunctionType::get(CGM.Int32Ty, /*isVarArg=*/true)
|
||||
->getPointerTo()
|
||||
->getPointerTo();
|
||||
VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy->getPointerTo());
|
||||
VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
|
||||
llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField);
|
||||
CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr());
|
||||
}
|
||||
|
|
|
@ -94,23 +94,23 @@ namespace InitVTable {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr
|
||||
// CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i8***
|
||||
// CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
|
||||
// CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i32 (...)***
|
||||
// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]]
|
||||
// CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)*** {{%.*}}
|
||||
// CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)** [[VTBL]], i64 0
|
||||
// CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)** [[FNP]]
|
||||
// CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]])
|
||||
// CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i8***
|
||||
// CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i32 (...)***
|
||||
// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]]
|
||||
// CHECK-NEXT: ret void
|
||||
B::B() : A(foo()) {}
|
||||
|
||||
// CHECK-LABEL: define void @_ZN10InitVTable1BC2Ei(%"struct.InitVTable::B"* %this, i32 %x) unnamed_addr
|
||||
// CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5
|
||||
// CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i8***
|
||||
// CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i32 (...)***
|
||||
// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]]
|
||||
// CHECK-NEXT: ret void
|
||||
B::B(int x) : A(x + 5) {}
|
||||
}
|
||||
|
|
|
@ -4,4 +4,4 @@ struct A { virtual void a(); };
|
|||
A x(A& y) { return y; }
|
||||
|
||||
// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A* dereferenceable({{[0-9]+}})) unnamed_addr
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**)
|
||||
|
|
|
@ -148,8 +148,8 @@ void f(B b1) {
|
|||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_(
|
||||
// CHECK: [[THIS:%.*]] = load [[A]]**
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i8***
|
||||
// CHECK-NEXT: store i8** getelementptr inbounds ([4 x i8*]* @_ZTVN12rdar138169401AE, i64 0, i64 2), i8*** [[T0]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)***
|
||||
// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN12rdar138169401AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
|
||||
// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
|
||||
// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s -O1 | FileCheck %s --check-prefix=O1
|
||||
// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s -O1 | FileCheck %s --check-prefix=O1
|
||||
|
||||
// Check that GlobalOpt can eliminate static constructors for simple implicit
|
||||
// constructors. This is a targetted integration test to make sure that LLVM's
|
||||
// optimizers are able to process Clang's IR. GlobalOpt in particular is
|
||||
// sensitive to the casts we emit.
|
||||
|
||||
// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
|
||||
// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_ctor_globalopt.cpp, i8* null }]
|
||||
|
||||
// CHECK-LABEL: define internal void @_GLOBAL__sub_I_ctor_globalopt.cpp()
|
||||
// CHECK: call void @
|
||||
// CHECK-NOT: call
|
||||
|
||||
// O1: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
|
||||
|
||||
struct A {
|
||||
virtual void f();
|
||||
int a;
|
||||
};
|
||||
struct B : virtual A {
|
||||
virtual void g();
|
||||
int b;
|
||||
};
|
||||
B b;
|
|
@ -150,35 +150,35 @@ void emit_ctors() {
|
|||
Left l;
|
||||
// CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"
|
||||
// CHECK-NOT: getelementptr
|
||||
// CHECK: store [1 x i8*]* @"\01??_7Left@@6B@"
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Left@@6B@" to i32 (...)**)
|
||||
// CHECK: ret
|
||||
|
||||
Right r;
|
||||
// CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"
|
||||
// CHECK-NOT: getelementptr
|
||||
// CHECK: store [1 x i8*]* @"\01??_7Right@@6B@"
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Right@@6B@" to i32 (...)**)
|
||||
// CHECK: ret
|
||||
|
||||
ChildOverride co;
|
||||
// CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
|
||||
// CHECK: %[[THIS:.*]] = load %struct.ChildOverride**
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to [1 x i8*]**
|
||||
// CHECK: store [1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@", [1 x i8*]** %[[VFPTR]]
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
||||
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
|
||||
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 4
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [1 x i8*]**
|
||||
// CHECK: store [1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@", [1 x i8*]** %[[VFPTR]]
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
||||
// CHECK: ret
|
||||
|
||||
GrandchildOverride gc;
|
||||
// CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
|
||||
// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride**
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to [1 x i8*]**
|
||||
// CHECK: store [1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@", [1 x i8*]** %[[VFPTR]]
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
||||
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
|
||||
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 4
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [1 x i8*]**
|
||||
// CHECK: store [1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@", [1 x i8*]** %[[VFPTR]]
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
||||
// CHECK: ret
|
||||
}
|
||||
|
||||
|
|
|
@ -75,8 +75,8 @@ void C::foo() {}
|
|||
void check_vftable_offset() {
|
||||
C c;
|
||||
// The vftable pointer should point at the beginning of the vftable.
|
||||
// CHECK: [[THIS_PTR:%[0-9]+]] = bitcast %"struct.basic::C"* {{.*}} to [2 x i8*]**
|
||||
// CHECK: store [2 x i8*]* @"\01??_7C@basic@@6B@", [2 x i8*]** [[THIS_PTR]]
|
||||
// CHECK: [[THIS_PTR:%[0-9]+]] = bitcast %"struct.basic::C"* {{.*}} to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([2 x i8*]* @"\01??_7C@basic@@6B@" to i32 (...)**), i32 (...)*** [[THIS_PTR]]
|
||||
}
|
||||
|
||||
void call_complete_dtor(C *obj_ptr) {
|
||||
|
|
|
@ -32,8 +32,8 @@ B::B() {
|
|||
// ...
|
||||
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
||||
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %{{.*}}
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [3 x i8*]**
|
||||
// CHECK: store [3 x i8*]* @"\01??_7B@@6B@", [3 x i8*]** %[[VFPTR]]
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
||||
|
||||
// Initialize vtorDisp:
|
||||
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
||||
|
@ -65,8 +65,8 @@ B::~B() {
|
|||
// ...
|
||||
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
||||
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %{{.*}}
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [3 x i8*]**
|
||||
// CHECK: store [3 x i8*]* @"\01??_7B@@6B@", [3 x i8*]** %[[VFPTR]]
|
||||
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
||||
|
||||
// Initialize vtorDisp:
|
||||
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
||||
|
@ -245,9 +245,9 @@ struct D : virtual A, virtual B, virtual C {
|
|||
D::D() {
|
||||
// CHECK-LABEL: define x86_thiscallcc %"struct.multiple_vbases::D"* @"\01??0D@multiple_vbases@@QAE@XZ"
|
||||
// Just make sure we emit 3 vtordisps after initializing vfptrs.
|
||||
// CHECK: store [1 x i8*]* @"\01??_7D@multiple_vbases@@6BA@1@@", [1 x i8*]** %{{.*}}
|
||||
// CHECK: store [1 x i8*]* @"\01??_7D@multiple_vbases@@6BB@1@@", [1 x i8*]** %{{.*}}
|
||||
// CHECK: store [1 x i8*]* @"\01??_7D@multiple_vbases@@6BC@1@@", [1 x i8*]** %{{.*}}
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
|
||||
// ...
|
||||
// CHECK: store i32 %{{.*}}, i32* %{{.*}}
|
||||
// CHECK: store i32 %{{.*}}, i32* %{{.*}}
|
||||
|
@ -396,8 +396,8 @@ C::~C() {
|
|||
// In this case "this" points to the most derived class, so no GEPs needed.
|
||||
// CHECK-NOT: getelementptr
|
||||
// CHECK-NOT: bitcast
|
||||
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to [1 x i8*]**
|
||||
// CHECK: store [1 x i8*]* @"\01??_7C@test4@@6BB@1@@", [1 x i8*]** %[[VFPTR_i8]]
|
||||
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
|
||||
|
||||
foo(this);
|
||||
// CHECK: ret
|
||||
|
@ -431,8 +431,8 @@ E::~E() {
|
|||
// In this case "this" points to the most derived class, so no GEPs needed.
|
||||
// CHECK-NOT: getelementptr
|
||||
// CHECK-NOT: bitcast
|
||||
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to [1 x i8*]**
|
||||
// CHECK: store [1 x i8*]* @"\01??_7E@test4@@6BD@1@@", [1 x i8*]** %[[VFPTR_i8]]
|
||||
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to i32 (...)***
|
||||
// CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
|
||||
foo(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ int fn() {
|
|||
|
||||
// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1SC2Ev(%struct.S* %this)
|
||||
// CHECK: call x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %{{[.0-9A-Z_a-z]+}})
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1S, i64 0, i64 2), i8*** %{{[.0-9A-Z_a-z]+}}
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1S, i64 0, i64 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %this)
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1I, i64 0, i64 2), i8*** %{{[.0-9A-Z_a-z]+}}
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1I, i64 0, i64 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
|
||||
|
|
|
@ -11,7 +11,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test11AD2Ev
|
||||
// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2), i8***
|
||||
// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test21AD2Ev
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2), i8***
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A() {
|
||||
f();
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test31AD2Ev
|
||||
// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2), i8***
|
||||
// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A() {
|
||||
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test41AD2Ev
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2), i8***
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test51AD2Ev
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2), i8***
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test61AD2Ev
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2), i8***
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test71AD2Ev
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2), i8***
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ struct A {
|
|||
};
|
||||
|
||||
// CHECK-LABEL: define void @_ZN5Test81AD2Ev
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2), i8***
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
|
||||
A::~A()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ struct A : Base {
|
|||
|
||||
// CHECK-LABEL: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr
|
||||
// CHECK: call void @_ZN4BaseC2Ev(
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**)
|
||||
// CHECK: call void @_ZN5FieldC1Ev(
|
||||
// CHECK: ret void
|
||||
A::A() { }
|
||||
|
||||
// CHECK-LABEL: define void @_ZN1AD2Ev(%struct.A* %this) unnamed_addr
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**)
|
||||
// CHECK: call void @_ZN5FieldD1Ev(
|
||||
// CHECK: call void @_ZN4BaseD2Ev(
|
||||
// CHECK: ret void
|
||||
|
@ -45,13 +45,13 @@ void f() { B b; }
|
|||
// CHECK: call void @_ZN1BC2Ev(
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) unnamed_addr
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**)
|
||||
// CHECK: call void @_ZN5FieldD1Ev(
|
||||
// CHECK: call void @_ZN4BaseD2Ev(
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(%struct.B* %this) unnamed_addr
|
||||
// CHECK: call void @_ZN4BaseC2Ev(
|
||||
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
|
||||
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**)
|
||||
// CHECK: call void @_ZN5FieldC1Ev
|
||||
// CHECK: ret void
|
||||
|
|
Loading…
Reference in New Issue