From: Nikita Popov Date: Thu, 6 Oct 2022 10:36:10 +0000 (+0200) Subject: [RelativeVTablesABI] Convert tests to opaque pointers (NFC) X-Git-Tag: upstream/17.0.6~31416 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=89810cee544db09fbf7d578c6e93db7a9cb0d9e5;p=platform%2Fupstream%2Fllvm.git [RelativeVTablesABI] Convert tests to opaque pointers (NFC) Converted using https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34 with manual fixup, primarily to drop check lines for types that no longer appear with opaque pointers. --- diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-inheritance.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-inheritance.cpp index 6990a06..cd3ce22 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-inheritance.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-inheritance.cpp @@ -1,28 +1,23 @@ // Diamond inheritance. // A more complicated multiple inheritance example that includes longer chain of inheritance and a common ancestor. -// RUN: %clang_cc1 -no-opaque-pointers %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s - -// CHECK-DAG: %class.B = type { %class.A } -// CHECK-DAG: %class.A = type { i32 (...)** } -// CHECK-DAG: %class.C = type { %class.A } -// CHECK-DAG: %class.D = type { %class.B, %class.C } +// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s // VTable for B should contain offset to top (0), RTTI pointer, A::foo(), and B::barB(). -// CHECK: @_ZTV1B.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i8* }** @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4 +// CHECK: @_ZTV1B.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4 // VTable for C should contain offset to top (0), RTTI pointer, A::foo(), and C::barC(). -// CHECK: @_ZTV1C.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i8* }** @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4 +// CHECK: @_ZTV1C.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4 // VTable for D should be similar to the mutiple inheritance example where this // vtable contains 2 inner vtables: // - 1st table containing D::foo(), B::barB(), and D::baz(). // - 2nd table containing a thunk to D::foo() and C::barC(). -// CHECK: @_ZTV1D.local = private unnamed_addr constant { [5 x i32], [4 x i32] } { [5 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }** @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.D*)* dso_local_equivalent @_ZN1D3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.D*)* dso_local_equivalent @_ZN1D3bazEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32)], [4 x i32] [i32 -8, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }** @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 1, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.D*)* dso_local_equivalent @_ZThn8_N1D3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 1, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 1, i32 2) to i64)) to i32)] }, align 4 +// CHECK: @_ZTV1D.local = private unnamed_addr constant { [5 x i32], [4 x i32] } { [5 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1D3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1D3bazEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 2) to i64)) to i32)], [4 x i32] [i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZThn8_N1D3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 2) to i64)) to i32)] }, align 4 -// @_ZTV1B ={{.*}} unnamed_addr alias { [4 x i32] }, { [4 x i32] }* @_ZTV1B.local -// @_ZTV1C ={{.*}} unnamed_addr alias { [4 x i32] }, { [4 x i32] }* @_ZTV1C.local -// @_ZTV1D ={{.*}} unnamed_addr alias { [5 x i32], [4 x i32] }, { [5 x i32], [4 x i32] }* @_ZTV1D.local +// @_ZTV1B ={{.*}} unnamed_addr alias { [4 x i32] }, ptr @_ZTV1B.local +// @_ZTV1C ={{.*}} unnamed_addr alias { [4 x i32] }, ptr @_ZTV1C.local +// @_ZTV1D ={{.*}} unnamed_addr alias { [5 x i32], [4 x i32] }, ptr @_ZTV1D.local class A { public: diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp index 0cd4636..f6cf834 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp @@ -1,68 +1,55 @@ // Diamond virtual inheritance. // This should cover virtual inheritance, construction vtables, and VTTs. -// RUN: %clang_cc1 -no-opaque-pointers %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s +// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s // Class A contains a vtable ptr, then int, then padding -// CHECK-DAG: %class.B = type { i32 (...)**, %class.A.base } -// CHECK-DAG: %class.A.base = type <{ i32 (...)**, i32 }> -// CHECK-DAG: %class.A = type <{ i32 (...)**, i32, [4 x i8] }> -// CHECK-DAG: %class.C = type { i32 (...)**, %class.A.base } -// CHECK-DAG: %class.D = type { %class.B.base, %class.C.base, %class.A.base } -// CHECK-DAG: %class.B.base = type { i32 (...)** } -// CHECK-DAG: %class.C.base = type { i32 (...)** } // VTable for B. Contains an extra field at the start for the virtual-base offset. -// CHECK: @_ZTV1B.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1B.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1B.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 +// CHECK: @_ZTV1B.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 // VTT for B -// CHECK: @_ZTT1B ={{.*}} unnamed_addr constant [2 x i8*] [i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1B.local, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1B.local, i32 0, inrange i32 1, i32 3) to i8*)], align 8 +// CHECK: @_ZTT1B ={{.*}} unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, inrange i32 1, i32 3)], align 8 // VTable for C -// CHECK: @_ZTV1C.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1C.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1C.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 +// CHECK: @_ZTV1C.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 // VTT for C -// CHECK: @_ZTT1C ={{.*}} unnamed_addr constant [2 x i8*] [i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1C.local, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1C.local, i32 0, inrange i32 1, i32 3) to i8*)], align 8 +// CHECK: @_ZTT1C ={{.*}} unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, inrange i32 1, i32 3)], align 8 // VTable for D -// CHECK: @_ZTV1D.local = private unnamed_addr constant { [5 x i32], [4 x i32], [4 x i32] } { [5 x i32] [i32 16, i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }** @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.D*)* dso_local_equivalent @_ZN1D3bazEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 8, i32 -8, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }** @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 1, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -16, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }** @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 2, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, i32 2, i32 3) to i64)) to i32)] }, align 4 +// CHECK: @_ZTV1D.local = private unnamed_addr constant { [5 x i32], [4 x i32], [4 x i32] } { [5 x i32] [i32 16, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1D3bazEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 8, i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -16, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 2, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 2, i32 3) to i64)) to i32)] }, align 4 // VTT for D -// CHECK: @_ZTT1D ={{.*}} unnamed_addr constant [7 x i8*] [i8* bitcast (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D0_1B.local, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D0_1B.local, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D8_1C.local, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D8_1C.local, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i32* getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local, i32 0, inrange i32 1, i32 3) to i8*)], align 8 +// CHECK: @_ZTT1D ={{.*}} unnamed_addr constant [7 x ptr] [ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, inrange i32 2, i32 3), ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, inrange i32 1, i32 3)], align 8 // Construction vtable for B-in-D -// CHECK: @_ZTC1D0_1B.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 16, i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D0_1B.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D0_1B.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -16, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D0_1B.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D0_1B.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 +// CHECK: @_ZTC1D0_1B.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 16, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -16, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 // Construction vtable for C-in-D -// CHECK: @_ZTC1D8_1C.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D8_1C.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D8_1C.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64 }** @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D8_1C.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D8_1C.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 +// CHECK: @_ZTC1D8_1C.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 -// CHECK: @_ZTV1B ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1B.local -// CHECK: @_ZTV1C ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTV1C.local -// CHECK: @_ZTC1D0_1B ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D0_1B.local -// CHECK: @_ZTC1D8_1C ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, { [4 x i32], [4 x i32] }* @_ZTC1D8_1C.local -// CHECK: @_ZTV1D ={{.*}} unnamed_addr alias { [5 x i32], [4 x i32], [4 x i32] }, { [5 x i32], [4 x i32], [4 x i32] }* @_ZTV1D.local +// CHECK: @_ZTV1B ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, ptr @_ZTV1B.local +// CHECK: @_ZTV1C ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, ptr @_ZTV1C.local +// CHECK: @_ZTC1D0_1B ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local +// CHECK: @_ZTC1D8_1C ={{.*}} unnamed_addr alias { [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local +// CHECK: @_ZTV1D ={{.*}} unnamed_addr alias { [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local -// CHECK: define{{.*}} void @_Z5D_fooP1D(%class.D* noundef %d) local_unnamed_addr +// CHECK: define{{.*}} void @_Z5D_fooP1D(ptr noundef %d) local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: [[d:%[0-9]+]] = bitcast %class.D* %d to i8** -// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load i8*, i8** [[d]], align 8 +// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load ptr, ptr %d, align 8 // This normally would've been -24 (8 bytes for the virtual call/base offset, 8 // bytes for the offset to top, and 8 bytes for the RTTI pointer), but since all // components in the vtable are halved to 4 bytes, the offset is halved to -12. -// CHECK-NEXT: [[vbase_offset_ptr:%[a-z0-9.]+]] = getelementptr i8, i8* [[vtable]], i64 -12 +// CHECK-NEXT: [[vbase_offset_ptr:%[a-z0-9.]+]] = getelementptr i8, ptr [[vtable]], i64 -12 -// CHECK-NEXT: [[vbase_offset_ptr2:%[a-z0-9.]+]] = bitcast i8* [[vbase_offset_ptr]] to i32* -// CHECK-NEXT: [[vbase_offset:%[a-z0-9.]+]] = load i32, i32* [[vbase_offset_ptr2]], align 4 -// CHECK-NEXT: [[d:%[0-9]+]] = bitcast %class.D* %d to i8* +// CHECK-NEXT: [[vbase_offset:%[a-z0-9.]+]] = load i32, ptr [[vbase_offset_ptr]], align 4 // CHECK-NEXT: [[vbase_offset2:%.+]] = sext i32 [[vbase_offset]] to i64 -// CHECK-NEXT: [[add_ptr:%[a-z0-9.]+]] = getelementptr inbounds i8, i8* [[d]], i64 [[vbase_offset2]] -// CHECK-NEXT: [[a:%[0-9]+]] = bitcast i8* [[add_ptr]] to %class.A* -// CHECK-NEXT: [[a_i8_ptr:%[0-9]+]] = bitcast i8* [[add_ptr]] to i8** -// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load i8*, i8** [[a_i8_ptr]], align 8 -// CHECK-NEXT: [[ptr:%[0-9]+]] = tail call i8* @llvm.load.relative.i32(i8* [[vtable]], i32 0) -// CHECK-NEXT: [[method:%[0-9]+]] = bitcast i8* [[ptr]] to void (%class.A*)* -// CHECK-NEXT: call void [[method]](%class.A* {{[^,]*}} [[a]]) +// CHECK-NEXT: [[add_ptr:%[a-z0-9.]+]] = getelementptr inbounds i8, ptr %d, i64 [[vbase_offset2]] +// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load ptr, ptr [[add_ptr]], align 8 +// CHECK-NEXT: [[ptr:%[0-9]+]] = tail call ptr @llvm.load.relative.i32(ptr [[vtable]], i32 0) +// CHECK-NEXT: call void [[ptr]](ptr {{[^,]*}} [[add_ptr]]) // CHECK-NEXT: ret void // CHECK-NEXT: } diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp index 90598b0..20b9557 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp @@ -1,51 +1,46 @@ // dynamic_cast // Ensure that dynamic casting works normally -// RUN: %clang_cc1 -no-opaque-pointers %s -triple=aarch64-unknown-fuchsia -O3 -S -o - -emit-llvm | FileCheck %s +// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O3 -S -o - -emit-llvm | FileCheck %s -// CHECK: define{{.*}} %class.A* @_Z6upcastP1B(%class.B* noundef readnone %b) local_unnamed_addr +// CHECK: define{{.*}} ptr @_Z6upcastP1B(ptr noundef readnone returned %b) local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: [[a:%[0-9]+]] = getelementptr %class.B, %class.B* %b, i64 0, i32 0 -// CHECK-NEXT: ret %class.A* [[a]] +// CHECK-NEXT: ret ptr %b // CHECK-NEXT: } -// CHECK: define{{.*}} %class.B* @_Z8downcastP1A(%class.A* noundef readonly %a) local_unnamed_addr +// CHECK: define{{.*}} ptr @_Z8downcastP1A(ptr noundef readonly %a) local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq %class.A* %a, null +// CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq ptr %a, null // CHECK-NEXT: br i1 [[isnull]], label %[[dynamic_cast_end:[a-z0-9._]+]], label %[[dynamic_cast_notnull:[a-z0-9._]+]] // CHECK: [[dynamic_cast_notnull]]: -// CHECK-NEXT: [[a:%[0-9]+]] = bitcast %class.A* %a to i8* -// CHECK-NEXT: [[as_b:%[0-9]+]] = tail call i8* @__dynamic_cast(i8* nonnull [[a]], i8* nonnull bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* nonnull bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i64 0) -// CHECK-NEXT: [[b:%[0-9]+]] = bitcast i8* [[as_b]] to %class.B* +// CHECK-NEXT: [[as_b:%[0-9]+]] = tail call ptr @__dynamic_cast(ptr nonnull %a, ptr nonnull @_ZTI1A, ptr nonnull @_ZTI1B, i64 0) // CHECK-NEXT: br label %[[dynamic_cast_end]] // CHECK: [[dynamic_cast_end]]: -// CHECK-NEXT: [[res:%[0-9]+]] = phi %class.B* [ [[b]], %[[dynamic_cast_notnull]] ], [ null, %entry ] -// CHECK-NEXT: ret %class.B* [[res]] +// CHECK-NEXT: [[res:%[0-9]+]] = phi ptr [ [[as_b]], %[[dynamic_cast_notnull]] ], [ null, %entry ] +// CHECK-NEXT: ret ptr [[res]] // CHECK-NEXT: } -// CHECK: declare i8* @__dynamic_cast(i8*, i8*, i8*, i64) local_unnamed_addr +// CHECK: declare ptr @__dynamic_cast(ptr, ptr, ptr, i64) local_unnamed_addr -// CHECK: define{{.*}} %class.B* @_Z8selfcastP1B(%class.B* noundef readnone returned %b) local_unnamed_addr +// CHECK: define{{.*}} ptr @_Z8selfcastP1B(ptr noundef readnone returned %b) local_unnamed_addr // CHECK-NEXT: entry -// CHECK-NEXT: ret %class.B* %b +// CHECK-NEXT: ret ptr %b // CHECK-NEXT: } -// CHECK: define{{.*}} i8* @_Z9void_castP1B(%class.B* noundef readonly %b) local_unnamed_addr +// CHECK: define{{.*}} ptr @_Z9void_castP1B(ptr noundef readonly %b) local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq %class.B* %b, null +// CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq ptr %b, null // CHECK-NEXT: br i1 [[isnull]], label %[[dynamic_cast_end:[a-z0-9._]+]], label %[[dynamic_cast_notnull:[a-z0-9._]+]] // CHECK: [[dynamic_cast_notnull]]: -// CHECK-DAG: [[b2:%[0-9]+]] = bitcast %class.B* %b to i32** -// CHECK-DAG: [[vtable:%[a-z0-9]+]] = load i32*, i32** [[b2]], align 8 -// CHECK-DAG: [[offset_ptr:%.+]] = getelementptr inbounds i32, i32* [[vtable]], i64 -2 -// CHECK-DAG: [[offset_to_top:%.+]] = load i32, i32* [[offset_ptr]], align 4 -// CHECK-DAG: [[b:%[0-9]+]] = bitcast %class.B* %b to i8* +// CHECK-DAG: [[vtable:%[a-z0-9]+]] = load ptr, ptr %b, align 8 +// CHECK-DAG: [[offset_ptr:%.+]] = getelementptr inbounds i32, ptr [[vtable]], i64 -2 +// CHECK-DAG: [[offset_to_top:%.+]] = load i32, ptr [[offset_ptr]], align 4 // CHECK-DAG: [[offset_to_top2:%.+]] = sext i32 [[offset_to_top]] to i64 -// CHECK-DAG: [[casted:%.+]] = getelementptr inbounds i8, i8* [[b]], i64 [[offset_to_top2]] +// CHECK-DAG: [[casted:%.+]] = getelementptr inbounds i8, ptr %b, i64 [[offset_to_top2]] // CHECK-NEXT: br label %[[dynamic_cast_end]] // CHECK: [[dynamic_cast_end]]: -// CHECK-NEXT: [[res:%[0-9]+]] = phi i8* [ [[casted]], %[[dynamic_cast_notnull]] ], [ null, %entry ] -// CHECK-NEXT: ret i8* [[res]] +// CHECK-NEXT: [[res:%[0-9]+]] = phi ptr [ [[casted]], %[[dynamic_cast_notnull]] ], [ null, %entry ] +// CHECK-NEXT: ret ptr [[res]] // CHECK-NEXT: } class A { diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/multiple-inheritance.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/multiple-inheritance.cpp index fbd4151..632cf34 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/multiple-inheritance.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/multiple-inheritance.cpp @@ -1,33 +1,26 @@ // Multiple inheritance. -// RUN: %clang_cc1 -no-opaque-pointers %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s - -// CHECK: %class.C = type { %class.A, %class.B } -// CHECK: %class.A = type { i32 (...)** } -// CHECK: %class.B = type { i32 (...)** } +// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s // VTable for C contains 2 sub-vtables (represented as 2 structs). The first contains the components for B and the second contains the components for C. The RTTI ptr in both arrays still point to the RTTI struct for C. // The component for bar() instead points to a thunk which redirects to C::bar() which overrides B::bar(). // Now that we have a class with 2 parents, the offset to top in the second array is non-zero. -// CHECK: @_ZTV1C.local = private unnamed_addr constant { [4 x i32], [3 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }** @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [3 x i32] }, { [4 x i32], [3 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZN1C3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [3 x i32] }, { [4 x i32], [3 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZN1C3barEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [3 x i32] }, { [4 x i32], [3 x i32] }* @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32)], [3 x i32] [i32 -8, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }** @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [3 x i32] }, { [4 x i32], [3 x i32] }* @_ZTV1C.local, i32 0, i32 1, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.C*)* dso_local_equivalent @_ZThn8_N1C3barEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32], [3 x i32] }, { [4 x i32], [3 x i32] }* @_ZTV1C.local, i32 0, i32 1, i32 2) to i64)) to i32)] }, align 4 +// CHECK: @_ZTV1C.local = private unnamed_addr constant { [4 x i32], [3 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [3 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [3 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C3barEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [3 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 2) to i64)) to i32)], [3 x i32] [i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [3 x i32] }, ptr @_ZTV1C.local, i32 0, i32 1, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZThn8_N1C3barEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [3 x i32] }, ptr @_ZTV1C.local, i32 0, i32 1, i32 2) to i64)) to i32)] }, align 4 -// CHECK: @_ZTV1C ={{.*}} unnamed_addr alias { [4 x i32], [3 x i32] }, { [4 x i32], [3 x i32] }* @_ZTV1C.local +// CHECK: @_ZTV1C ={{.*}} unnamed_addr alias { [4 x i32], [3 x i32] }, ptr @_ZTV1C.local -// CHECK: define{{.*}} void @_Z8C_foobarP1C(%class.C* noundef %c) local_unnamed_addr +// CHECK: define{{.*}} void @_Z8C_foobarP1C(ptr noundef %c) local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: [[c:%[0-9]+]] = bitcast %class.C* %c to i8** -// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load i8*, i8** [[c]], align 8 +// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load ptr, ptr %c, align 8 // Offset 0 to get first method -// CHECK-NEXT: [[ptr1:%[0-9]+]] = tail call i8* @llvm.load.relative.i32(i8* [[vtable]], i32 0) -// CHECK-NEXT: [[method1:%[0-9]+]] = bitcast i8* [[ptr1]] to void (%class.C*)* -// CHECK-NEXT: call void [[method1]](%class.C* {{[^,]*}} %c) -// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load i8*, i8** [[c]], align 8 +// CHECK-NEXT: [[ptr1:%[0-9]+]] = tail call ptr @llvm.load.relative.i32(ptr [[vtable]], i32 0) +// CHECK-NEXT: call void [[ptr1]](ptr {{[^,]*}} %c) +// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load ptr, ptr %c, align 8 // Offset by 4 to get the next bar() -// CHECK-NEXT: [[ptr2:%[0-9]+]] = tail call i8* @llvm.load.relative.i32(i8* [[vtable]], i32 4) -// CHECK-NEXT: [[method2:%[0-9]+]] = bitcast i8* [[ptr2]] to void (%class.C*)* -// CHECK-NEXT: call void [[method2]](%class.C* {{[^,]*}} %c) +// CHECK-NEXT: [[ptr2:%[0-9]+]] = tail call ptr @llvm.load.relative.i32(ptr [[vtable]], i32 4) +// CHECK-NEXT: call void [[ptr2]](ptr {{[^,]*}} %c) // CHECK-NEXT: ret void // CHECK-NEXT: } diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp index 7d558c7..78db999 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp @@ -1,49 +1,45 @@ // Check typeid() + type_info -// RUN: %clang_cc1 -no-opaque-pointers %s -triple=aarch64-unknown-fuchsia -O3 -S -o - -emit-llvm -fcxx-exceptions -fexceptions | FileCheck %s +// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O3 -S -o - -emit-llvm -fcxx-exceptions -fexceptions | FileCheck %s -// CHECK: %class.A = type { i32 (...)** } -// CHECK: %class.B = type { %class.A } -// CHECK: %"class.std::type_info" = type { i32 (...)**, i8* } +// CHECK: %"class.std::type_info" = type { ptr, ptr } // CHECK: $_ZTI1A.rtti_proxy = comdat any // CHECK: $_ZTI1B.rtti_proxy = comdat any -// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global i8* +// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global ptr // CHECK: @_ZTS1A ={{.*}} constant [3 x i8] c"1A\00", align 1 -// CHECK: @_ZTI1A ={{.*}} constant { i8*, i8* } { i8* getelementptr inbounds (i8, i8* bitcast (i8** @_ZTVN10__cxxabiv117__class_type_infoE to i8*), i32 8), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1A, i32 0, i32 0) }, align 8 -// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8* +// CHECK: @_ZTI1A ={{.*}} constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, align 8 +// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global ptr // CHECK: @_ZTS1B ={{.*}} constant [3 x i8] c"1B\00", align 1 -// CHECK: @_ZTI1B ={{.*}} constant { i8*, i8*, i8* } { i8* getelementptr inbounds (i8, i8* bitcast (i8** @_ZTVN10__cxxabiv120__si_class_type_infoE to i8*), i32 8), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0), i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*) }, align 8 -// CHECK: @_ZTI1A.rtti_proxy = hidden unnamed_addr constant { i8*, i8* }* @_ZTI1A, comdat -// CHECK: @_ZTI1B.rtti_proxy = hidden unnamed_addr constant { i8*, i8*, i8* }* @_ZTI1B, comdat +// CHECK: @_ZTI1B ={{.*}} constant { ptr, ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 8), ptr @_ZTS1B, ptr @_ZTI1A }, align 8 +// CHECK: @_ZTI1A.rtti_proxy = hidden unnamed_addr constant ptr @_ZTI1A, comdat +// CHECK: @_ZTI1B.rtti_proxy = hidden unnamed_addr constant ptr @_ZTI1B, comdat -// CHECK: define {{.*}}%"class.std::type_info"* @_Z11getTypeInfov() local_unnamed_addr +// CHECK: define {{.*}}ptr @_Z11getTypeInfov() local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: ret %"class.std::type_info"* bitcast ({ i8*, i8* }* @_ZTI1A to %"class.std::type_info"*) +// CHECK-NEXT: ret ptr @_ZTI1A // CHECK-NEXT: } -// CHECK: define{{.*}} i8* @_Z7getNamev() local_unnamed_addr +// CHECK: define{{.*}} ptr @_Z7getNamev() local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: ret i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1A, i64 0, i64 0) +// CHECK-NEXT: ret ptr @_ZTS1A // CHECK-NEXT: } -// CHECK: define{{.*}} i1 @_Z5equalP1A(%class.A* noundef readonly %a) local_unnamed_addr +// CHECK: define{{.*}} i1 @_Z5equalP1A(ptr noundef readonly %a) local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq %class.A* %a, null +// CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq ptr %a, null // CHECK-NEXT: br i1 [[isnull]], label %[[bad_typeid:[a-z0-9._]+]], label %[[end:[a-z0-9.+]+]] // CHECK: [[bad_typeid]]: // CHECK-NEXT: tail call void @__cxa_bad_typeid() // CHECK-NEXT: unreachable // CHECK: [[end]]: -// CHECK-NEXT: [[type_info_ptr3:%[0-9]+]] = bitcast %class.A* %a to i8** -// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load i8*, i8** [[type_info_ptr3]] -// CHECK-NEXT: [[type_info_ptr:%[0-9]+]] = tail call i8* @llvm.load.relative.i32(i8* [[vtable]], i32 -4) -// CHECK-NEXT: [[type_info_ptr2:%[0-9]+]] = bitcast i8* [[type_info_ptr]] to %"class.std::type_info"** -// CHECK-NEXT: [[type_info_ptr:%[0-9]+]] = load %"class.std::type_info"*, %"class.std::type_info"** [[type_info_ptr2]], align 8 -// CHECK-NEXT: [[name_ptr:%[a-z0-9._]+]] = getelementptr inbounds %"class.std::type_info", %"class.std::type_info"* [[type_info_ptr]], i64 0, i32 1 -// CHECK-NEXT: [[name:%[0-9]+]] = load i8*, i8** [[name_ptr]], align 8 -// CHECK-NEXT: [[eq:%[a-z0-9.]+]] = icmp eq i8* [[name]], getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i64 0, i64 0) +// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load ptr, ptr %a +// CHECK-NEXT: [[type_info_ptr:%[0-9]+]] = tail call ptr @llvm.load.relative.i32(ptr [[vtable]], i32 -4) +// CHECK-NEXT: [[type_info_ptr2:%[0-9]+]] = load ptr, ptr [[type_info_ptr]], align 8 +// CHECK-NEXT: [[name_ptr:%[a-z0-9._]+]] = getelementptr inbounds %"class.std::type_info", ptr [[type_info_ptr2]], i64 0, i32 1 +// CHECK-NEXT: [[name:%[0-9]+]] = load ptr, ptr [[name_ptr]], align 8 +// CHECK-NEXT: [[eq:%[a-z0-9.]+]] = icmp eq ptr [[name]], @_ZTS1B // CHECK-NEXT: ret i1 [[eq]] // CHECK-NEXT: } diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/vbase-offset.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/vbase-offset.cpp index 12358b6..7c5f2db 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/vbase-offset.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/vbase-offset.cpp @@ -1,19 +1,15 @@ // Check that the pointer adjustment from the virtual base offset is loaded as a // 32-bit int. -// RUN: %clang_cc1 -no-opaque-pointers %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm | FileCheck %s +// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm | FileCheck %s // CHECK-LABEL: @_ZTv0_n12_N7Derived1fEi( // CHECK-NEXT: entry: -// CHECK: [[this:%.+]] = bitcast %class.Derived* %this1 to i8* -// CHECK-NEXT: [[this2:%.+]] = bitcast i8* [[this]] to i8** -// CHECK-NEXT: [[vtable:%.+]] = load i8*, i8** [[this2]], align 8 -// CHECK-NEXT: [[vbase_offset_ptr:%.+]] = getelementptr inbounds i8, i8* [[vtable]], i64 -12 -// CHECK-NEXT: [[vbase_offset_ptr2:%.+]] = bitcast i8* [[vbase_offset_ptr]] to i32* -// CHECK-NEXT: [[vbase_offset:%.+]] = load i32, i32* [[vbase_offset_ptr2]], align 4 -// CHECK-NEXT: [[adj_this:%.+]] = getelementptr inbounds i8, i8* [[this]], i32 [[vbase_offset]] -// CHECK-NEXT: [[adj_this2:%.+]] = bitcast i8* [[adj_this]] to %class.Derived* -// CHECK: [[call:%.+]] = tail call noundef i32 @_ZN7Derived1fEi(%class.Derived* noundef{{[^,]*}} [[adj_this2]], i32 noundef {{.*}}) +// CHECK: [[vtable:%.+]] = load ptr, ptr %this1, align 8 +// CHECK-NEXT: [[vbase_offset_ptr:%.+]] = getelementptr inbounds i8, ptr [[vtable]], i64 -12 +// CHECK-NEXT: [[vbase_offset:%.+]] = load i32, ptr [[vbase_offset_ptr]], align 4 +// CHECK-NEXT: [[adj_this:%.+]] = getelementptr inbounds i8, ptr %this1, i32 [[vbase_offset]] +// CHECK: [[call:%.+]] = tail call noundef i32 @_ZN7Derived1fEi(ptr noundef{{[^,]*}} [[adj_this]], i32 noundef {{.*}}) // CHECK: ret i32 [[call]] class Base { diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/virtual-function-call.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/virtual-function-call.cpp index c42e00c..abb11d7 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/virtual-function-call.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/virtual-function-call.cpp @@ -1,14 +1,12 @@ // Check that we call llvm.load.relative() on a vtable function call. -// RUN: %clang_cc1 -no-opaque-pointers %s -triple=aarch64-unknown-fuchsia -O3 -S -o - -emit-llvm | FileCheck %s +// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O3 -S -o - -emit-llvm | FileCheck %s -// CHECK: define{{.*}} void @_Z5A_fooP1A(%class.A* noundef %a) local_unnamed_addr +// CHECK: define{{.*}} void @_Z5A_fooP1A(ptr noundef %a) local_unnamed_addr // CHECK-NEXT: entry: -// CHECK-NEXT: [[this:%[0-9]+]] = bitcast %class.A* %a to i8** -// CHECK-NEXT: %vtable1 = load i8*, i8** [[this]] -// CHECK-NEXT: [[func_ptr:%[0-9]+]] = tail call i8* @llvm.load.relative.i32(i8* %vtable1, i32 0) -// CHECK-NEXT: [[func:%[0-9]+]] = bitcast i8* [[func_ptr]] to void (%class.A*)* -// CHECK-NEXT: tail call void [[func]](%class.A* {{[^,]*}} %a) +// CHECK-NEXT: %vtable = load ptr, ptr %a +// CHECK-NEXT: [[func_ptr:%[0-9]+]] = tail call ptr @llvm.load.relative.i32(ptr %vtable, i32 0) +// CHECK-NEXT: tail call void [[func_ptr]](ptr {{[^,]*}} %a) // CHECK-NEXT: ret void // CHECK-NEXT: }