[clang] c2985a3 - [Clang] Convert some tests to opaque pointers (NFC)
Nikita Popov via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 8 01:38:17 PDT 2023
Author: Nikita Popov
Date: 2023-06-08T10:38:08+02:00
New Revision: c2985a330cd5c418488cbd87bd7a2922d6a8f7da
URL: https://github.com/llvm/llvm-project/commit/c2985a330cd5c418488cbd87bd7a2922d6a8f7da
DIFF: https://github.com/llvm/llvm-project/commit/c2985a330cd5c418488cbd87bd7a2922d6a8f7da.diff
LOG: [Clang] Convert some tests to opaque pointers (NFC)
Added:
Modified:
clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
clang/test/CodeGenCXX/microsoft-abi-structors.cpp
clang/test/CodeGenCXX/microsoft-abi-this-nullable.cpp
clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
Removed:
################################################################################
diff --git a/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
index 28cf226450da5..1cc0e9af571c3 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
struct ClassWithoutDtor {
char x;
@@ -7,7 +7,7 @@ struct ClassWithoutDtor {
void check_array_no_cookies() {
// CHECK: define dso_local void @"?check_array_no_cookies@@YAXXZ"() [[NUW:#[0-9]+]]
-// CHECK: call noalias noundef nonnull i8* @"??_U at YAPAXI@Z"(i32 noundef 42)
+// CHECK: call noalias noundef nonnull ptr @"??_U at YAPAXI@Z"(i32 noundef 42)
ClassWithoutDtor *array = new ClassWithoutDtor[42];
// CHECK: call void @"??_V at YAXPAX@Z"(
@@ -24,16 +24,13 @@ void check_array_cookies_simple() {
// CHECK: define {{.*}} @"?check_array_cookies_simple@@YAXXZ"()
ClassWithDtor *array = new ClassWithDtor[42];
-// CHECK: [[ALLOCATED:%.*]] = call noalias noundef nonnull i8* @"??_U at YAPAXI@Z"(i32 noundef 46)
+// CHECK: [[ALLOCATED:%.*]] = call noalias noundef nonnull ptr @"??_U at YAPAXI@Z"(i32 noundef 46)
// 46 = 42 + size of cookie (4)
-// CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32*
-// CHECK: store i32 42, i32* [[COOKIE]]
-// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, i8* [[ALLOCATED]], i32 4
-// CHECK: bitcast i8* [[ARRAY]] to [[CLASS:%.*]]*
+// CHECK: store i32 42, ptr [[ALLOCATED]]
+// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[ALLOCATED]], i32 4
delete [] array;
-// CHECK: [[ARRAY_AS_CHAR:%.*]] = bitcast [[CLASS]]* {{%.*}} to i8*
-// CHECK: getelementptr inbounds i8, i8* [[ARRAY_AS_CHAR]], i32 -4
+// CHECK: getelementptr inbounds i8, ptr {{%.*}}, i32 -4
}
struct __attribute__((aligned(8))) ClassWithAlignment {
@@ -46,16 +43,13 @@ struct __attribute__((aligned(8))) ClassWithAlignment {
void check_array_cookies_aligned() {
// CHECK: define {{.*}} @"?check_array_cookies_aligned@@YAXXZ"()
ClassWithAlignment *array = new ClassWithAlignment[42];
-// CHECK: [[ALLOCATED:%.*]] = call noalias noundef nonnull i8* @"??_U at YAPAXI@Z"(i32 noundef 344)
+// CHECK: [[ALLOCATED:%.*]] = call noalias noundef nonnull ptr @"??_U at YAPAXI@Z"(i32 noundef 344)
// 344 = 42*8 + size of cookie (8, due to alignment)
-// CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32*
-// CHECK: store i32 42, i32* [[COOKIE]]
-// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, i8* [[ALLOCATED]], i32 8
-// CHECK: bitcast i8* [[ARRAY]] to [[CLASS:%.*]]*
+// CHECK: store i32 42, ptr [[ALLOCATED]]
+// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[ALLOCATED]], i32 8
delete [] array;
-// CHECK: [[ARRAY_AS_CHAR:%.*]] = bitcast [[CLASS]]*
-// CHECK: getelementptr inbounds i8, i8* [[ARRAY_AS_CHAR]], i32 -8
+// CHECK: getelementptr inbounds i8, ptr {{.*}}, i32 -8
}
namespace PR23990 {
@@ -63,7 +57,7 @@ struct S {
char x[42];
void operator delete[](void *p, __SIZE_TYPE__);
// CHECK-LABEL: define dso_local void @"?delete_s at PR23990@@YAXPAUS at 1@@Z"(
- // CHECK: call void @"??_VS at PR23990@@SAXPAXI at Z"(i8* noundef {{.*}}, i32 noundef 42)
+ // CHECK: call void @"??_VS at PR23990@@SAXPAXI at Z"(ptr noundef {{.*}}, i32 noundef 42)
};
void delete_s(S *s) { delete[] s; }
}
diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
index 89944053c6816..80ea63e2a1e10 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -Wno-non-pod-varargs -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
+// RUN: %clang_cc1 -Wno-non-pod-varargs -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
#include <stdarg.h>
@@ -19,14 +19,14 @@ int foo(A a, ...) {
return sum;
}
-// CHECK-LABEL: define dso_local noundef i32 @"?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca(<{ %struct.A }>) %0, ...)
+// CHECK-LABEL: define dso_local noundef i32 @"?foo@@YAHUA@@ZZ"(ptr inalloca(<{ %struct.A }>) %0, ...)
int main() {
return foo(A(3), 1, 2, 3);
}
// CHECK-LABEL: define dso_local noundef i32 @main()
// CHECK: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.A, i32, i32, i32 }>
-// CHECK: call noundef i32 {{.*bitcast.*}}@"?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca(<{ %struct.A, i32, i32, i32 }>) %[[argmem]])
+// CHECK: call noundef i32 (ptr, ...) @"?foo@@YAHUA@@ZZ"{{.*}}(ptr inalloca(<{ %struct.A, i32, i32, i32 }>) %[[argmem]])
void varargs_zero(...);
void varargs_one(int, ...);
@@ -41,10 +41,10 @@ void call_var_args() {
}
// CHECK-LABEL: define dso_local void @"?call_var_args@@YAXXZ"()
-// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca(<{ %struct.A }>) %{{.*}})
-// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca(<{ i32, %struct.A }>) %{{.*}})
-// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca(<{ i32, i32, %struct.A }>) %{{.*}})
-// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca(<{ i32, i32, i32, %struct.A }>) %{{.*}})
+// CHECK: call void {{.*varargs_zero.*}}(ptr inalloca(<{ %struct.A }>) %{{.*}})
+// CHECK: call void {{.*varargs_one.*}}(ptr inalloca(<{ i32, %struct.A }>) %{{.*}})
+// CHECK: call void {{.*varargs_two.*}}(ptr inalloca(<{ i32, i32, %struct.A }>) %{{.*}})
+// CHECK: call void {{.*varargs_three.*}}(ptr inalloca(<{ i32, i32, i32, %struct.A }>) %{{.*}})
// CHECK-LABEL: declare dso_local void @"?varargs_zero@@YAXZZ"(...)
// CHECK-LABEL: declare dso_local void @"?varargs_one@@YAXHZZ"(i32 noundef, ...)
diff --git a/clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
index 7601e6293ec90..3a82c76b4c145 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
struct A {
constexpr A(int x) : x(x) {}
@@ -7,7 +7,7 @@ struct A {
};
A a(42);
-// CHECK: @"?a@@3UA@@A" = dso_local global { { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"??_7A@@6B@", i32 42 }, align 4
+// CHECK: @"?a@@3UA@@A" = dso_local global %struct.A { ptr @"??_7A@@6B@", i32 42 }, align 4
struct B {
constexpr B(int y) : y(y) {}
@@ -20,4 +20,4 @@ struct C : A, B {
};
C c;
-// CHECK: @"?c@@3UC@@A" = dso_local global { { [1 x i8*] }*, i32, { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"??_7C@@6BA@@@", i32 777, { [1 x i8*] }* @"??_7C@@6BB@@@", i32 13 }
+// CHECK: @"?c@@3UC@@A" = dso_local global { ptr, i32, ptr, i32 } { ptr @"??_7C@@6BA@@@", i32 777, ptr @"??_7C@@6BB@@@", i32 13 }
diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
index ed2c257bac494..2a5aef6e19da4 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
// RUN: -mconstructor-aliases -fexceptions -fcxx-exceptions \
// RUN: -O1 -disable-llvm-passes \
// RUN: | FileCheck -check-prefix WIN64 %s
@@ -25,7 +25,7 @@ extern "C" void catch_all() {
// WIN64: %[[catchswitch:[^ ]*]] = catchswitch within none [label %[[catchpad_lpad:[^ ]*]]] unwind to caller
//
// WIN64: [[catchpad_lpad]]
-// WIN64: catchpad within %[[catchswitch]] [i8* null, i32 64, i8* null]
+// WIN64: catchpad within %[[catchswitch]] [ptr null, i32 64, ptr null]
// WIN64: call void @recover()
// WIN64: catchret from %{{.*}} to label %[[catchret:[^ ]*]]
//
@@ -47,17 +47,16 @@ extern "C" void catch_int() {
}
// WIN64-LABEL: define dso_local void @catch_int()
-// WIN64: catchpad within %{{[^ ]*}} [%rtti.TypeDescriptor2* @"??_R0H at 8", i32 0, i32* %[[e_addr:[^\]]*]]]
+// WIN64: catchpad within %{{[^ ]*}} [ptr @"??_R0H at 8", i32 0, ptr %[[e_addr:.*]]]
//
// The catchpad instruction starts the lifetime of 'e'. Unfortunately, that
// leaves us with nowhere to put lifetime.start, so we don't emit lifetime
// markers for now.
// WIN64-NOT: lifetime.start
//
-// WIN64: %[[e_i8:[^ ]*]] = bitcast i32* %[[e_addr]] to i8*
// WIN64-NOT: lifetime.start
// WIN64: call void @handle_exception
-// WIN64-SAME: (i8* noundef %[[e_i8]])
+// WIN64-SAME: (ptr noundef %[[e_addr]])
// WIN64-NOT: lifetime.end
// WIN64: catchret
@@ -69,7 +68,7 @@ extern "C" void catch_int_unnamed() {
}
// WIN64-LABEL: define dso_local void @catch_int_unnamed()
-// WIN64: catchpad within %{{.*}} [%rtti.TypeDescriptor2* @"??_R0H at 8", i32 0, i8* null]
+// WIN64: catchpad within %{{.*}} [ptr @"??_R0H at 8", i32 0, ptr null]
// WIN64: catchret
struct A {
@@ -96,9 +95,8 @@ extern "C" void catch_a_byval() {
// WIN64-LABEL: define dso_local void @catch_a_byval()
// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A
-// WIN64: catchpad within %{{[^ ]*}} [%rtti.TypeDescriptor7* @"??_R0?AUA@@@8", i32 0, %struct.A* %[[e_addr]]]
-// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A* %[[e_addr]] to i8*
-// WIN64: call void @handle_exception(i8* noundef %[[e_i8]])
+// WIN64: catchpad within %{{[^ ]*}} [ptr @"??_R0?AUA@@@8", i32 0, ptr %[[e_addr]]]
+// WIN64: call void @handle_exception(ptr noundef %[[e_addr]])
// WIN64: catchret
extern "C" void catch_a_ref() {
@@ -110,11 +108,10 @@ extern "C" void catch_a_ref() {
}
// WIN64-LABEL: define dso_local void @catch_a_ref()
-// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A*
-// WIN64: catchpad within %{{[^ ]*}} [%rtti.TypeDescriptor7* @"??_R0?AUA@@@8", i32 8, %struct.A** %[[e_addr]]]
-// WIN64: %[[eptr:[^ ]*]] = load %struct.A*, %struct.A** %[[e_addr]]
-// WIN64: %[[eptr_i8:[^ ]*]] = bitcast %struct.A* %[[eptr]] to i8*
-// WIN64: call void @handle_exception(i8* noundef %[[eptr_i8]])
+// WIN64: %[[e_addr:[^ ]*]] = alloca ptr
+// WIN64: catchpad within %{{[^ ]*}} [ptr @"??_R0?AUA@@@8", i32 8, ptr %[[e_addr]]]
+// WIN64: %[[eptr:[^ ]*]] = load ptr, ptr %[[e_addr]]
+// WIN64: call void @handle_exception(ptr noundef %[[eptr]])
// WIN64: catchret
extern "C" void fn_with_exc_spec() throw(int) {
@@ -145,7 +142,7 @@ extern "C" void catch_nested() {
// WIN64: %[[catchswitch_outer_scope:[^ ]*]] = catchswitch within none [label %[[catch_int_outer:[^ ]*]]] unwind to caller
//
// WIN64: [[catch_int_outer]]
-// WIN64: %[[catchpad:[^ ]*]] = catchpad within %[[catchswitch_outer_scope]] [%rtti.TypeDescriptor2* @"??_R0H at 8", i32 0, i8* null]
+// WIN64: %[[catchpad:[^ ]*]] = catchpad within %[[catchswitch_outer_scope]] [ptr @"??_R0H at 8", i32 0, ptr null]
// WIN64: invoke void @might_throw()
// WIN64-NEXT: to label %[[cont2:[^ ]*]] unwind label %[[catchswitch_inner:[^ ]*]]
//
@@ -153,7 +150,7 @@ extern "C" void catch_nested() {
// WIN64: %[[catchswitch_inner_scope:[^ ]*]] = catchswitch within %[[catchpad]] [label %[[catch_int_inner:[^ ]*]]] unwind to caller
//
// WIN64: [[catch_int_inner]]
-// WIN64: catchpad within %[[catchswitch_inner_scope]] [%rtti.TypeDescriptor2* @"??_R0H at 8", i32 0, i8* null]
+// WIN64: catchpad within %[[catchswitch_inner_scope]] [ptr @"??_R0H at 8", i32 0, ptr null]
// WIN64-NEXT: call void @might_throw()
// WIN64: catchret {{.*}} to label %[[catchret2:[^ ]*]]
//
diff --git a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index c464c1c7071ea..6e4b7f259727b 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -1,14 +1,14 @@
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck -allow-deprecated-dag-overlap %s
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck -allow-deprecated-dag-overlap %s
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
namespace pr37399 {
template <typename T>
struct Functor {
void (T::*PtrToMemberFunction)();
};
-// CHECK-DAG: %"struct.pr37399::Functor" = type { i8* }
+// CHECK-DAG: %"struct.pr37399::Functor" = type { ptr }
template <typename SomeType>
class SimpleDerivedFunctor;
@@ -77,20 +77,20 @@ class VirtuallyDerivedFunctor
pr37399::DerivedFunctor<int> BFunctor;
// CHECK-DAG: @"?BFunctor@@3V?$DerivedFunctor at H@pr37399@@A" = dso_local global %"[[BFUNCTOR:class.pr37399::DerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
// CHECK-DAG: %"[[BFUNCTOR]]" = type { %"[[BFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]" }
-// CHECK-DAG: %"[[BFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+// CHECK-DAG: %"[[BFUNCTORBASE]]" = type { { ptr, i32, i32, i32 } }
pr37399::DerivedFunctor<void> AFunctor;
// CHECK-DAG: @"?AFunctor@@3V?$DerivedFunctor at X@pr37399@@A" = dso_local global %"[[AFUNCTOR:class.pr37399::DerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
// CHECK-DAG: %"[[AFUNCTOR]]" = type { %"[[AFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]" }
-// CHECK-DAG: %"[[AFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+// CHECK-DAG: %"[[AFUNCTORBASE]]" = type { { ptr, i32, i32, i32 } }
pr37399::MultiplyDerivedFunctor<int> DFunctor;
// CHECK-DAG: @"?DFunctor@@3V?$MultiplyDerivedFunctor at H@pr37399@@A" = dso_local global %"[[DFUNCTOR:class.pr37399::MultiplyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
// CHECK-DAG: %"[[DFUNCTOR]]" = type { %"[[DFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", %"class.pr37399::MultipleBase", [6 x i8] }
-// CHECK-DAG: %"[[DFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+// CHECK-DAG: %"[[DFUNCTORBASE]]" = type { { ptr, i32, i32, i32 } }
pr37399::MultiplyDerivedFunctor<void> CFunctor;
// CHECK-DAG: @"?CFunctor@@3V?$MultiplyDerivedFunctor at X@pr37399@@A" = dso_local global %"[[CFUNCTOR:class.pr37399::MultiplyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
// CHECK-DAG: %"[[CFUNCTOR]]" = type { %"[[CFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", %"class.pr37399::MultipleBase", [6 x i8] }
-// CHECK-DAG: %"[[CFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+// CHECK-DAG: %"[[CFUNCTORBASE]]" = type { { ptr, i32, i32, i32 } }
pr37399::VirtuallyDerivedFunctor<int> FFunctor;
// CHECK-DAG: @"?FFunctor@@3V?$VirtuallyDerivedFunctor at H@pr37399@@A" = dso_local global %"[[FFUNCTOR:class.pr37399::VirtuallyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
@@ -99,8 +99,8 @@ pr37399::VirtuallyDerivedFunctor<void> EFunctor;
// CHECK-DAG: @"?EFunctor@@3V?$VirtuallyDerivedFunctor at X@pr37399@@A" = dso_local global %"[[EFUNCTOR:class.pr37399::VirtuallyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
// CHECK-DAG: %"[[EFUNCTOR]]" = type { %"class.pr37399::VirtBaseFunctor.base", %"class.pr37399::VirtualBase" }
-// CHECK-DAG: %"class.pr37399::VirtBaseFunctor.base" = type <{ %"[[VFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", i32*, [4 x i8] }>
-// CHECK-DAG: %"[[VFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+// CHECK-DAG: %"class.pr37399::VirtBaseFunctor.base" = type <{ %"[[VFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", ptr, [4 x i8] }>
+// CHECK-DAG: %"[[VFUNCTORBASE]]" = type { { ptr, i32, i32, i32 } }
namespace pr37399 {
void SingleInheritanceFnPtrCall() {
@@ -170,17 +170,17 @@ void PR26313_f(PR26313_FUNC *p) { delete p; }
struct PR26313_Z;
int PR26313_Z::**a = nullptr;
int PR26313_Z::*b = *a;
-// CHECK-DAG: @"?a@@3PAPQPR26313_Z@@HA" = dso_local global %0* null, align 4
+// CHECK-DAG: @"?a@@3PAPQPR26313_Z@@HA" = dso_local global ptr null, align 4
// CHECK-DAG: @"?b@@3PQPR26313_Z@@HQ1@" = dso_local global { i32, i32, i32 } { i32 0, i32 0, i32 -1 }, align 4
namespace PR20947 {
struct A;
int A::**a = nullptr;
-// CHECK-DAG: @"?a at PR20947@@3PAPQA at 1@HA" = dso_local global %{{.*}}* null, align 4
+// CHECK-DAG: @"?a at PR20947@@3PAPQA at 1@HA" = dso_local global ptr null, align 4
struct B;
int B::*&b = b;
-// CHECK-DAG: @"?b at PR20947@@3AAPQB at 1@HA" = dso_local global %{{.*}}* null, align 4
+// CHECK-DAG: @"?b at PR20947@@3AAPQB at 1@HA" = dso_local global ptr null, align 4
}
namespace PR20017 {
@@ -190,7 +190,7 @@ struct A {
};
struct B;
auto a = &A<B>::m_fn1;
-// CHECK-DAG: @"?a at PR20017@@3P8?$A at UB@PR20017@@@1 at AEPQB@1 at HXZQ21@" = dso_local global i8* bitcast ({ i32, i32, i32 } ({{.*}}*)* @"?m_fn1@?$A at UB@PR20017@@@PR20017@@QAEPQB at 2@HXZ" to i8*), align 4
+// CHECK-DAG: @"?a at PR20017@@3P8?$A at UB@PR20017@@@1 at AEPQB@1 at HXZQ21@" = dso_local global ptr @"?m_fn1@?$A at UB@PR20017@@@PR20017@@QAEPQB at 2@HXZ", align 4
}
#ifndef INCOMPLETE_VIRTUAL
@@ -259,9 +259,9 @@ int UnspecSingle::*us_d_memptr;
void (Single ::*s_f_memptr)();
void (Multiple::*m_f_memptr)();
void (Virtual ::*v_f_memptr)();
-// CHECK: @"?s_f_memptr@@3P8Single@@AEXXZQ1@" = dso_local global i8* null, align 4
-// CHECK: @"?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = dso_local global { i8*, i32 } zeroinitializer, align 4
-// CHECK: @"?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = dso_local global { i8*, i32, i32 } zeroinitializer, align 4
+// CHECK: @"?s_f_memptr@@3P8Single@@AEXXZQ1@" = dso_local global ptr null, align 4
+// CHECK: @"?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = dso_local global { ptr, i32 } zeroinitializer, align 4
+// CHECK: @"?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = dso_local global { ptr, i32, i32 } zeroinitializer, align 4
// We can define Unspecified after locking in the inheritance model.
struct Unspecified : Multiple, Virtual {
@@ -281,15 +281,15 @@ void (Virtual ::*v_f_mp)() = &Virtual::foo;
void (Unspecified::*u_f_mp)() = &Unspecified::foo;
void (UnspecSingle::*us_f_mp)() = &UnspecSingle::foo;
// CHECK: @"?s_f_mp at Const@@3P8Single@@AEXXZQ2@" =
-// CHECK: global i8* bitcast ({{.*}} @"?foo at Single@@QAEXXZ" to i8*), align 4
+// CHECK: global ptr @"?foo at Single@@QAEXXZ", align 4
// CHECK: @"?m_f_mp at Const@@3P8Multiple@@AEXXZQ2@" =
-// CHECK: global { i8*, i32 } { i8* bitcast ({{.*}} @"?foo at B2@@QAEXXZ" to i8*), i32 4 }, align 4
+// CHECK: global { ptr, i32 } { ptr @"?foo at B2@@QAEXXZ", i32 4 }, align 4
// CHECK: @"?v_f_mp at Const@@3P8Virtual@@AEXXZQ2@" =
-// CHECK: global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"?foo at Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 4
+// CHECK: global { ptr, i32, i32 } { ptr @"?foo at Virtual@@QAEXXZ", i32 0, i32 0 }, align 4
// CHECK: @"?u_f_mp at Const@@3P8Unspecified@@AEXXZQ2@" =
-// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"?foo at Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4
+// CHECK: global { ptr, i32, i32, i32 } { ptr @"?foo at Unspecified@@QAEXXZ", i32 0, i32 0, i32 0 }, align 4
// CHECK: @"?us_f_mp at Const@@3P8UnspecSingle@@AEXXZQ2@" =
-// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"?foo at UnspecSingle@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4
+// CHECK: global { ptr, i32, i32, i32 } { ptr @"?foo at UnspecSingle@@QAEXXZ", i32 0, i32 0, i32 0 }, align 4
}
namespace CastParam {
@@ -306,16 +306,16 @@ struct C : B, A { int c; };
void (A::*ptr1)(void *) = (void (A::*)(void *)) &A::foo;
// CHECK: @"?ptr1 at CastParam@@3P8A at 1@AEXPAX at ZQ21@" =
-// CHECK: global i8* bitcast (void ({{.*}})* @"?foo at A@CastParam@@QAEXPAU12@@Z" to i8*), align 4
+// CHECK: global ptr @"?foo at A@CastParam@@QAEXPAU12@@Z", align 4
// Try a reinterpret_cast followed by a memptr conversion.
void (C::*ptr2)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) &A::foo;
// CHECK: @"?ptr2 at CastParam@@3P8C at 1@AEXPAX at ZQ21@" =
-// CHECK: global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"?foo at A@CastParam@@QAEXPAU12@@Z" to i8*), i32 4 }, align 4
+// CHECK: global { ptr, i32 } { ptr @"?foo at A@CastParam@@QAEXPAU12@@Z", i32 4 }, align 4
void (C::*ptr3)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) (void (A::*)(A *)) 0;
// CHECK: @"?ptr3 at CastParam@@3P8C at 1@AEXPAX at ZQ21@" =
-// CHECK: global { i8*, i32 } zeroinitializer, align 4
+// CHECK: global { ptr, i32 } zeroinitializer, align 4
struct D : C {
virtual void isPolymorphic();
@@ -347,24 +347,24 @@ void EmitNonVirtualMemberPointers() {
void (Unspecified::*u_f_memptr)() = &Unspecified::foo;
void (UnspecWithVBPtr::*u2_f_memptr)() = &UnspecWithVBPtr::foo;
// CHECK: define dso_local void @"?EmitNonVirtualMemberPointers@@YAXXZ"() {{.*}} {
-// CHECK: alloca i8*, align 4
-// CHECK: alloca { i8*, i32 }, align 4
-// CHECK: alloca { i8*, i32, i32 }, align 4
-// CHECK: alloca { i8*, i32, i32, i32 }, align 4
-// CHECK: store i8* bitcast (void (%{{.*}}*)* @"?foo at Single@@QAEXXZ" to i8*), i8** %{{.*}}, align 4
-// CHECK: store { i8*, i32 }
-// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo at Multiple@@QAEXXZ" to i8*), i32 0 },
-// CHECK: { i8*, i32 }* %{{.*}}, align 4
-// CHECK: store { i8*, i32, i32 }
-// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo at Virtual@@QAEXXZ" to i8*), i32 0, i32 0 },
-// CHECK: { i8*, i32, i32 }* %{{.*}}, align 4
-// CHECK: store { i8*, i32, i32, i32 }
-// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo at Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 },
-// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4
-// CHECK: store { i8*, i32, i32, i32 }
-// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo at UnspecWithVBPtr@@QAEXXZ" to i8*),
+// CHECK: alloca ptr, align 4
+// CHECK: alloca { ptr, i32 }, align 4
+// CHECK: alloca { ptr, i32, i32 }, align 4
+// CHECK: alloca { ptr, i32, i32, i32 }, align 4
+// CHECK: store ptr @"?foo at Single@@QAEXXZ", ptr %{{.*}}, align 4
+// CHECK: store { ptr, i32 }
+// CHECK: { ptr @"?foo at Multiple@@QAEXXZ", i32 0 },
+// CHECK: ptr %{{.*}}, align 4
+// CHECK: store { ptr, i32, i32 }
+// CHECK: { ptr @"?foo at Virtual@@QAEXXZ", i32 0, i32 0 },
+// CHECK: ptr %{{.*}}, align 4
+// CHECK: store { ptr, i32, i32, i32 }
+// CHECK: { ptr @"?foo at Unspecified@@QAEXXZ", i32 0, i32 0, i32 0 },
+// CHECK: ptr %{{.*}}, align 4
+// CHECK: store { ptr, i32, i32, i32 }
+// CHECK: { ptr @"?foo at UnspecWithVBPtr@@QAEXXZ",
// CHECK: i32 0, i32 0, i32 0 },
-// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: ptr %{{.*}}, align 4
// CHECK: ret void
// CHECK: }
}
@@ -378,12 +378,12 @@ void podMemPtrs() {
// Check that member pointers use the right offsets and that null is -1.
// CHECK: define dso_local void @"?podMemPtrs@@YAXXZ"() {{.*}} {
// CHECK: %[[memptr:.*]] = alloca i32, align 4
-// CHECK-NEXT: store i32 0, i32* %[[memptr]], align 4
-// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4
-// CHECK-NEXT: %[[memptr_val:.*]] = load i32, i32* %[[memptr]], align 4
+// CHECK-NEXT: store i32 0, ptr %[[memptr]], align 4
+// CHECK-NEXT: store i32 4, ptr %[[memptr]], align 4
+// CHECK-NEXT: %[[memptr_val:.*]] = load i32, ptr %[[memptr]], align 4
// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], -1
// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
-// CHECK: store i32 -1, i32* %[[memptr]], align 4
+// CHECK: store i32 -1, ptr %[[memptr]], align 4
// CHECK: ret void
// CHECK: }
}
@@ -398,12 +398,12 @@ void polymorphicMemPtrs() {
// offset and use 0 to represent null.
// CHECK: define dso_local void @"?polymorphicMemPtrs@@YAXXZ"() {{.*}} {
// CHECK: %[[memptr:.*]] = alloca i32, align 4
-// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4
-// CHECK-NEXT: store i32 8, i32* %[[memptr]], align 4
-// CHECK-NEXT: %[[memptr_val:.*]] = load i32, i32* %[[memptr]], align 4
+// CHECK-NEXT: store i32 4, ptr %[[memptr]], align 4
+// CHECK-NEXT: store i32 8, ptr %[[memptr]], align 4
+// CHECK-NEXT: %[[memptr_val:.*]] = load i32, ptr %[[memptr]], align 4
// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], 0
// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
-// CHECK: store i32 0, i32* %[[memptr]], align 4
+// CHECK: store i32 0, ptr %[[memptr]], align 4
// CHECK: ret void
// CHECK: }
}
@@ -411,9 +411,9 @@ void polymorphicMemPtrs() {
bool nullTestDataUnspecified(int Unspecified::*mp) {
return mp;
// CHECK: define dso_local noundef zeroext i1 @"?nullTestDataUnspecified@@YA_NPQUnspecified@@H at Z"{{.*}} {
-// CHECK: %{{.*}} = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %{{.*}} = load { i32, i32, i32 }, ptr %{{.*}}, align 4
// CHECK: store { i32, i32, i32 } {{.*}} align 4
-// CHECK: %[[mp:.*]] = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[mp:.*]] = load { i32, i32, i32 }, ptr %{{.*}}, align 4
// CHECK: %[[mp0:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 0
// CHECK: %[[cmp0:.*]] = icmp ne i32 %[[mp0]], 0
// CHECK: %[[mp1:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 1
@@ -427,17 +427,17 @@ bool nullTestDataUnspecified(int Unspecified::*mp) {
// Pass this large type indirectly.
// X64-LABEL: define dso_local noundef zeroext i1 @"?nullTestDataUnspecified@@
-// X64: ({ i32, i32, i32 }* noundef %0)
+// X64: (ptr noundef %0)
}
bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) {
return mp;
// CHECK: define dso_local noundef zeroext i1 @"?nullTestFunctionUnspecified@@YA_NP8Unspecified@@AEXXZ at Z"{{.*}} {
-// CHECK: %{{.*}} = load { i8*, i32, i32, i32 }, { i8*, i32, i32, i32 }* %{{.*}}, align 4
-// CHECK: store { i8*, i32, i32, i32 } {{.*}} align 4
-// CHECK: %[[mp:.*]] = load { i8*, i32, i32, i32 }, { i8*, i32, i32, i32 }* %{{.*}}, align 4
-// CHECK: %[[mp0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[mp]], 0
-// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[mp0]], null
+// CHECK: %{{.*}} = load { ptr, i32, i32, i32 }, ptr %{{.*}}, align 4
+// CHECK: store { ptr, i32, i32, i32 } {{.*}} align 4
+// CHECK: %[[mp:.*]] = load { ptr, i32, i32, i32 }, ptr %{{.*}}, align 4
+// CHECK: %[[mp0:.*]] = extractvalue { ptr, i32, i32, i32 } %[[mp]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne ptr %[[mp0]], null
// CHECK: ret i1 %[[cmp0]]
// CHECK: }
}
@@ -447,28 +447,25 @@ int loadDataMemberPointerVirtual(Virtual *o, int Virtual::*memptr) {
// Test that we can unpack this aggregate member pointer and load the member
// data pointer.
// CHECK: define dso_local noundef i32 @"?loadDataMemberPointerVirtual@@YAHPAUVirtual@@PQ1 at H@Z"{{.*}} {
-// CHECK: %[[o:.*]] = load %{{.*}}*, %{{.*}}** %{{.*}}, align 4
-// CHECK: %[[memptr:.*]] = load { i32, i32 }, { i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[o:.*]] = load ptr, ptr %{{.*}}, align 4
+// CHECK: %[[memptr:.*]] = load { i32, i32 }, ptr %{{.*}}, align 4
// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 0
// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1
-// CHECK: %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8*
-// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %[[v6]], i32 0
-// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
-// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]]
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, ptr %[[o]], i32 0
+// CHECK: %[[vbtable:.*]] = load ptr, ptr %[[vbptr_a:.*]]
// CHECK: %[[memptr1_shr:.*]] = ashr exact i32 %[[memptr1]], 2
-// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr1_shr]]
-// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]]
-// CHECK: %[[v10:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]]
-// CHECK: %[[offset:.*]] = getelementptr inbounds i8, i8* %[[v10]], i32 %[[memptr0]]
-// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
-// CHECK: %[[v12:.*]] = load i32, i32* %[[v11]]
+// CHECK: %[[v7:.*]] = getelementptr inbounds i32, ptr %[[vbtable]], i32 %[[memptr1_shr]]
+// CHECK: %[[vbase_offs:.*]] = load i32, ptr %[[v7]]
+// CHECK: %[[v10:.*]] = getelementptr inbounds i8, ptr %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK: %[[offset:.*]] = getelementptr inbounds i8, ptr %[[v10]], i32 %[[memptr0]]
+// CHECK: %[[v12:.*]] = load i32, ptr %[[offset]]
// CHECK: ret i32 %[[v12]]
// CHECK: }
// A two-field data memptr on x64 gets coerced to i64 and is passed in a
// register or memory.
// X64-LABEL: define dso_local noundef i32 @"?loadDataMemberPointerVirtual@@YAHPEAUVirtual@@PEQ1 at H@Z"
-// X64: (%struct.Virtual* noundef %o, i64 %memptr.coerce)
+// X64: (ptr noundef %o, i64 %memptr.coerce)
}
int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) {
@@ -476,29 +473,26 @@ int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) {
// Test that we can unpack this aggregate member pointer and load the member
// data pointer.
// CHECK: define dso_local noundef i32 @"?loadDataMemberPointerUnspecified@@YAHPAUUnspecified@@PQ1 at H@Z"{{.*}} {
-// CHECK: %[[o:.*]] = load %{{.*}}*, %{{.*}}** %{{.*}}, align 4
-// CHECK: %[[memptr:.*]] = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[o:.*]] = load ptr, ptr %{{.*}}, align 4
+// CHECK: %[[memptr:.*]] = load { i32, i32, i32 }, ptr %{{.*}}, align 4
// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 0
// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 1
// CHECK: %[[memptr2:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 2
-// CHECK: %[[base:.*]] = bitcast %{{.*}}* %[[o]] to i8*
// CHECK: %[[is_vbase:.*]] = icmp ne i32 %[[memptr2]], 0
// CHECK: br i1 %[[is_vbase]], label %[[vadjust:.*]], label %[[skip:.*]]
//
// CHECK: [[vadjust]]
-// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %[[base]], i32 %[[memptr1]]
-// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
-// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]]
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, ptr %[[o]], i32 %[[memptr1]]
+// CHECK: %[[vbtable:.*]] = load ptr, ptr %[[vbptr_a:.*]]
// CHECK: %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2
-// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr2_shr]]
-// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]]
-// CHECK: %[[base_adj:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK: %[[v7:.*]] = getelementptr inbounds i32, ptr %[[vbtable]], i32 %[[memptr2_shr]]
+// CHECK: %[[vbase_offs:.*]] = load i32, ptr %[[v7]]
+// CHECK: %[[base_adj:.*]] = getelementptr inbounds i8, ptr %[[vbptr]], i32 %[[vbase_offs]]
//
// CHECK: [[skip]]
-// CHECK: %[[new_base:.*]] = phi i8* [ %[[base]], %{{.*}} ], [ %[[base_adj]], %[[vadjust]] ]
-// CHECK: %[[offset:.*]] = getelementptr inbounds i8, i8* %[[new_base]], i32 %[[memptr0]]
-// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
-// CHECK: %[[v12:.*]] = load i32, i32* %[[v11]]
+// CHECK: %[[new_base:.*]] = phi ptr [ %[[o]], %{{.*}} ], [ %[[base_adj]], %[[vadjust]] ]
+// CHECK: %[[offset:.*]] = getelementptr inbounds i8, ptr %[[new_base]], i32 %[[memptr0]]
+// CHECK: %[[v12:.*]] = load i32, ptr %[[offset]]
// CHECK: ret i32 %[[v12]]
// CHECK: }
}
@@ -507,25 +501,22 @@ void callMemberPointerSingle(Single *o, void (Single::*memptr)()) {
(o->*memptr)();
// Just look for an indirect thiscall.
// CHECK: define dso_local void @"?callMemberPointerSingle@@{{.*}} {{.*}} {
-// CHECK: call x86_thiscallcc void %{{.*}}(%{{.*}} %{{.*}})
+// CHECK: call x86_thiscallcc void %{{.*}}({{.*}} %{{.*}})
// CHECK: ret void
// CHECK: }
// X64-LABEL: define dso_local void @"?callMemberPointerSingle@@
-// X64: (%struct.Single* noundef %o, i8* %memptr)
-// X64: bitcast i8* %{{[^ ]*}} to void (%struct.Single*)*
+// X64: (ptr noundef %o, ptr %memptr)
// X64: ret void
}
void callMemberPointerMultiple(Multiple *o, void (Multiple::*memptr)()) {
(o->*memptr)();
// CHECK: define dso_local void @"?callMemberPointerMultiple@@{{.*}} {
-// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32 } %{{.*}}, 0
-// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32 } %{{.*}}, 1
-// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, i8* %{{.*}}, i32 %[[memptr1]]
-// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
-// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to {{.*}}
-// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK: %[[memptr0:.*]] = extractvalue { ptr, i32 } %{{.*}}, 0
+// CHECK: %[[memptr1:.*]] = extractvalue { ptr, i32 } %{{.*}}, 1
+// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 %[[memptr1]]
+// CHECK: call x86_thiscallcc void %[[memptr0]]({{.*}} %[[this_adjusted]])
// CHECK: ret void
// CHECK: }
}
@@ -534,20 +525,17 @@ void callMemberPointerVirtualBase(Virtual *o, void (Virtual::*memptr)()) {
(o->*memptr)();
// This shares a lot with virtual data member pointers.
// CHECK: define dso_local void @"?callMemberPointerVirtualBase@@{{.*}} {
-// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 0
-// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1
-// CHECK: %[[memptr2:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2
-// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %{{.*}}, i32 0
-// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
-// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]]
+// CHECK: %[[memptr0:.*]] = extractvalue { ptr, i32, i32 } %{{.*}}, 0
+// CHECK: %[[memptr1:.*]] = extractvalue { ptr, i32, i32 } %{{.*}}, 1
+// CHECK: %[[memptr2:.*]] = extractvalue { ptr, i32, i32 } %{{.*}}, 2
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 0
+// CHECK: %[[vbtable:.*]] = load ptr, ptr %[[vbptr_a:.*]]
// CHECK: %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2
-// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr2_shr]]
-// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]]
-// CHECK: %[[v10:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]]
-// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, i8* %[[v10]], i32 %[[memptr1]]
-// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to void ({{.*}})
-// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
-// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK: %[[v7:.*]] = getelementptr inbounds i32, ptr %[[vbtable]], i32 %[[memptr2_shr]]
+// CHECK: %[[vbase_offs:.*]] = load i32, ptr %[[v7]]
+// CHECK: %[[v10:.*]] = getelementptr inbounds i8, ptr %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, ptr %[[v10]], i32 %[[memptr1]]
+// CHECK: call x86_thiscallcc void %[[memptr0]]({{.*}} %[[this_adjusted]])
// CHECK: ret void
// CHECK: }
}
@@ -563,7 +551,7 @@ bool compareSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
// CHECK: }
// X64-LABEL: define dso_local noundef zeroext i1 @"?compareSingleFunctionMemptr@@
-// X64: (i8* %{{[^,]*}}, i8* %{{[^)]*}})
+// X64: (ptr %{{[^,]*}}, ptr %{{[^)]*}})
}
bool compareNeqSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
@@ -580,48 +568,48 @@ bool compareNeqSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
bool unspecFuncMemptrEq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
return l == r;
// CHECK: define dso_local noundef zeroext i1 @"?unspecFuncMemptrEq@@YA_NP8Unspecified@@AEXXZ0 at Z"{{.*}} {
-// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0
-// CHECK: %[[cmp0:.*]] = icmp eq i8* %[[lhs0]], %{{.*}}
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1
+// CHECK: %[[lhs0:.*]] = extractvalue { ptr, i32, i32, i32 } %[[l:.*]], 0
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r:.*]], 0
+// CHECK: %[[cmp0:.*]] = icmp eq ptr %[[lhs0]], %{{.*}}
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[l]], 1
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r]], 1
// CHECK: %[[cmp1:.*]] = icmp eq i32
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[l]], 2
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r]], 2
// CHECK: %[[cmp2:.*]] = icmp eq i32
// CHECK: %[[res12:.*]] = and i1 %[[cmp1]], %[[cmp2]]
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[l]], 3
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r]], 3
// CHECK: %[[cmp3:.*]] = icmp eq i32
// CHECK: %[[res123:.*]] = and i1 %[[res12]], %[[cmp3]]
-// CHECK: %[[iszero:.*]] = icmp eq i8* %[[lhs0]], null
+// CHECK: %[[iszero:.*]] = icmp eq ptr %[[lhs0]], null
// CHECK: %[[bits_or_null:.*]] = or i1 %[[res123]], %[[iszero]]
// CHECK: %{{.*}} = and i1 %[[bits_or_null]], %[[cmp0]]
// CHECK: ret i1 %{{.*}}
// CHECK: }
// X64-LABEL: define dso_local noundef zeroext i1 @"?unspecFuncMemptrEq@@
-// X64: ({ i8*, i32, i32, i32 }* noundef %0, { i8*, i32, i32, i32 }* noundef %1)
+// X64: (ptr noundef %0, ptr noundef %1)
}
bool unspecFuncMemptrNeq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
return l != r;
// CHECK: define dso_local noundef zeroext i1 @"?unspecFuncMemptrNeq@@YA_NP8Unspecified@@AEXXZ0 at Z"{{.*}} {
-// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0
-// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[lhs0]], %{{.*}}
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1
+// CHECK: %[[lhs0:.*]] = extractvalue { ptr, i32, i32, i32 } %[[l:.*]], 0
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r:.*]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne ptr %[[lhs0]], %{{.*}}
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[l]], 1
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r]], 1
// CHECK: %[[cmp1:.*]] = icmp ne i32
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[l]], 2
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r]], 2
// CHECK: %[[cmp2:.*]] = icmp ne i32
// CHECK: %[[res12:.*]] = or i1 %[[cmp1]], %[[cmp2]]
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3
-// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[l]], 3
+// CHECK: %{{.*}} = extractvalue { ptr, i32, i32, i32 } %[[r]], 3
// CHECK: %[[cmp3:.*]] = icmp ne i32
// CHECK: %[[res123:.*]] = or i1 %[[res12]], %[[cmp3]]
-// CHECK: %[[iszero:.*]] = icmp ne i8* %[[lhs0]], null
+// CHECK: %[[iszero:.*]] = icmp ne ptr %[[lhs0]], null
// CHECK: %[[bits_or_null:.*]] = and i1 %[[res123]], %[[iszero]]
// CHECK: %{{.*}} = or i1 %[[bits_or_null]], %[[cmp0]]
// CHECK: ret i1 %{{.*}}
@@ -646,24 +634,24 @@ bool unspecDataMemptrEq(int Unspecified::*l, int Unspecified::*r) {
// CHECK: }
// X64-LABEL: define dso_local noundef zeroext i1 @"?unspecDataMemptrEq@@
-// X64: ({ i32, i32, i32 }* noundef %0, { i32, i32, i32 }* noundef %1)
+// X64: (ptr noundef %0, ptr noundef %1)
}
void (Multiple::*convertB2FuncToMultiple(void (B2::*mp)()))() {
return mp;
// CHECK: define dso_local i64 @"?convertB2FuncToMultiple@@YAP8Multiple@@AEXXZP8B2@@AEXXZ at Z"{{.*}} {
// CHECK: store
-// CHECK: %[[mp:.*]] = load i8*, i8** %{{.*}}, align 4
-// CHECK: icmp ne i8* %[[mp]], null
+// CHECK: %[[mp:.*]] = load ptr, ptr %{{.*}}, align 4
+// CHECK: icmp ne ptr %[[mp]], null
// CHECK: br i1 %{{.*}} label %{{.*}}, label %{{.*}}
//
// memptr.convert: ; preds = %entry
-// CHECK: insertvalue { i8*, i32 } undef, i8* %[[mp]], 0
-// CHECK: insertvalue { i8*, i32 } %{{.*}}, i32 4, 1
+// CHECK: insertvalue { ptr, i32 } undef, ptr %[[mp]], 0
+// CHECK: insertvalue { ptr, i32 } %{{.*}}, i32 4, 1
// CHECK: br label
//
// memptr.converted: ; preds = %memptr.convert, %entry
-// CHECK: phi { i8*, i32 } [ zeroinitializer, %{{.*}} ], [ {{.*}} ]
+// CHECK: phi { ptr, i32 } [ zeroinitializer, %{{.*}} ], [ {{.*}} ]
// CHECK: }
}
@@ -671,23 +659,23 @@ void (B2::*convertMultipleFuncToB2(void (Multiple::*mp)()))() {
// FIXME: cl emits warning C4407 on this code because of the representation
// change. We might want to do the same.
return static_cast<void (B2::*)()>(mp);
-// FIXME: We should return i8* instead of i32 here. The ptrtoint cast prevents
+// FIXME: We should return ptr instead of i32 here. The ptrtoint cast prevents
// LLVM from optimizing away the branch. This is likely a bug in
// lib/CodeGen/TargetInfo.cpp with how we classify memptr types for returns.
//
// CHECK: define dso_local i32 @"?convertMultipleFuncToB2@@YAP8B2@@AEXXZP8Multiple@@AEXXZ at Z"{{.*}} {
// CHECK: store
-// CHECK: %[[src:.*]] = load { i8*, i32 }, { i8*, i32 }* %{{.*}}, align 4
-// CHECK: extractvalue { i8*, i32 } %[[src]], 0
-// CHECK: icmp ne i8* %{{.*}}, null
+// CHECK: %[[src:.*]] = load { ptr, i32 }, ptr %{{.*}}, align 4
+// CHECK: extractvalue { ptr, i32 } %[[src]], 0
+// CHECK: icmp ne ptr %{{.*}}, null
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
//
// memptr.convert: ; preds = %entry
-// CHECK: %[[fp:.*]] = extractvalue { i8*, i32 } %[[src]], 0
+// CHECK: %[[fp:.*]] = extractvalue { ptr, i32 } %[[src]], 0
// CHECK: br label
//
// memptr.converted: ; preds = %memptr.convert, %entry
-// CHECK: phi i8* [ null, %{{.*}} ], [ %[[fp]], %{{.*}} ]
+// CHECK: phi ptr [ null, %{{.*}} ], [ %[[fp]], %{{.*}} ]
// CHECK: }
}
@@ -702,27 +690,27 @@ void (D::*convertCToD(void (C::*mp)()))() {
return mp;
// CHECK: define dso_local void @"?convertCToD at Test1@@YAP8D at 1@AEXXZP8C at 1@AEXXZ at Z"{{.*}} {
// CHECK: store
-// CHECK: load { i8*, i32, i32 }, { i8*, i32, i32 }* %{{.*}}, align 4
-// CHECK: extractvalue { i8*, i32, i32 } %{{.*}}, 0
-// CHECK: icmp ne i8* %{{.*}}, null
+// CHECK: load { ptr, i32, i32 }, ptr %{{.*}}, align 4
+// CHECK: extractvalue { ptr, i32, i32 } %{{.*}}, 0
+// CHECK: icmp ne ptr %{{.*}}, null
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
//
// memptr.convert: ; preds = %entry
-// CHECK: extractvalue { i8*, i32, i32 } %{{.*}}, 0
-// CHECK: %[[nvoff:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1
-// CHECK: %[[vbidx:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2
+// CHECK: extractvalue { ptr, i32, i32 } %{{.*}}, 0
+// CHECK: %[[nvoff:.*]] = extractvalue { ptr, i32, i32 } %{{.*}}, 1
+// CHECK: %[[vbidx:.*]] = extractvalue { ptr, i32, i32 } %{{.*}}, 2
// CHECK: %[[is_nvbase:.*]] = icmp eq i32 %[[vbidx]], 0
// CHECK: %[[nv_disp:.*]] = add nsw i32 %[[nvoff]], 4
// CHECK: %[[nv_adj:.*]] = select i1 %[[is_nvbase]], i32 %[[nv_disp]], i32 0
// CHECK: %[[dst_adj:.*]] = select i1 %[[is_nvbase]], i32 4, i32 0
// CHECK: %[[adj:.*]] = sub nsw i32 %[[nv_adj]], %[[dst_adj]]
-// CHECK: insertvalue { i8*, i32, i32 } undef, i8* {{.*}}, 0
-// CHECK: insertvalue { i8*, i32, i32 } {{.*}}, i32 %[[adj]], 1
-// CHECK: insertvalue { i8*, i32, i32 } {{.*}}, i32 {{.*}}, 2
+// CHECK: insertvalue { ptr, i32, i32 } undef, ptr {{.*}}, 0
+// CHECK: insertvalue { ptr, i32, i32 } {{.*}}, i32 %[[adj]], 1
+// CHECK: insertvalue { ptr, i32, i32 } {{.*}}, i32 {{.*}}, 2
// CHECK: br label
//
// memptr.converted: ; preds = %memptr.convert, %entry
-// CHECK: phi { i8*, i32, i32 } [ { i8* null, i32 0, i32 -1 }, {{.*}} ], [ {{.*}} ]
+// CHECK: phi { ptr, i32, i32 } [ { ptr null, i32 0, i32 -1 }, {{.*}} ], [ {{.*}} ]
// CHECK: }
}
@@ -749,7 +737,7 @@ int A::*reinterpret(int B::*mp) {
int A::*reinterpret(int C::*mp) {
return reinterpret_cast<int A::*>(mp);
// CHECK: define dso_local i32 @"?reinterpret at Test2@@YAPQA at 1@HPQC at 1@H at Z"{{.*}} {
-// CHECK: %[[mp:.*]] = load i32, i32*
+// CHECK: %[[mp:.*]] = load i32, ptr
// CHECK: %[[cmp:.*]] = icmp ne i32 %[[mp]], 0
// CHECK: select i1 %[[cmp]], i32 %[[mp]], i32 -1
// CHECK: }
@@ -758,7 +746,7 @@ int A::*reinterpret(int C::*mp) {
}
namespace Test3 {
-// Make sure we cast 'this' to i8* before using GEP.
+// Make sure we cast 'this' to ptr before using GEP.
struct A {
int a;
@@ -767,11 +755,10 @@ struct A {
int *load_data(A *a, int A::*mp) {
return &(a->*mp);
-// CHECK-LABEL: define dso_local noundef i32* @"?load_data at Test3@@YAPAHPAUA at 1@PQ21 at H@Z"{{.*}} {
-// CHECK: %[[a:.*]] = load %"struct.Test3::A"*, %"struct.Test3::A"** %{{.*}}, align 4
-// CHECK: %[[mp:.*]] = load i32, i32* %{{.*}}, align 4
-// CHECK: %[[a_i8:.*]] = bitcast %"struct.Test3::A"* %[[a]] to i8*
-// CHECK: getelementptr inbounds i8, i8* %[[a_i8]], i32 %[[mp]]
+// CHECK-LABEL: define dso_local noundef ptr @"?load_data at Test3@@YAPAHPAUA at 1@PQ21 at H@Z"{{.*}} {
+// CHECK: %[[a:.*]] = load ptr, ptr %{{.*}}, align 4
+// CHECK: %[[mp:.*]] = load i32, ptr %{{.*}}, align 4
+// CHECK: getelementptr inbounds i8, ptr %[[a]], i32 %[[mp]]
// CHECK: }
}
@@ -787,15 +774,15 @@ void (C::*getmp())() {
return &C::g;
}
// CHECK-LABEL: define dso_local i64 @"?getmp at Test4@@YAP8C at 1@AEXXZXZ"()
-// CHECK: store { i8*, i32 } { i8* bitcast (void (%"struct.Test4::C"*, ...)* @"??_9C at Test4@@$BA at AE" to i8*), i32 4 }, { i8*, i32 }* %{{.*}}
+// CHECK: store { ptr, i32 } { ptr @"??_9C at Test4@@$BA at AE", i32 4 }, ptr %{{.*}}
//
-// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C at Test4@@$BA at AE"(%"struct.Test4::C"* noundef %this, ...) {{.*}} comdat
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C at Test4@@$BA at AE"(ptr noundef %this, ...) {{.*}} comdat
// CHECK-NOT: getelementptr
-// CHECK: load void (%"struct.Test4::C"*, ...)**, void (%"struct.Test4::C"*, ...)*** %{{.*}}
-// CHECK: getelementptr inbounds void (%"struct.Test4::C"*, ...)*, void (%"struct.Test4::C"*, ...)** %{{.*}}, i64 0
+// CHECK: load ptr, ptr %{{.*}}
+// CHECK: getelementptr inbounds ptr, ptr %{{.*}}, i64 0
// CHECK-NOT: getelementptr
-// CHECK: musttail call x86_thiscallcc void (%"struct.Test4::C"*, ...) %
+// CHECK: musttail call x86_thiscallcc void (ptr, ...) %
}
@@ -807,7 +794,7 @@ struct A {
struct B : public A {};
void test() { void (B::*a)() = &B::f; }
// CHECK-LABEL: define dso_local void @"?test at pr20007@@YAXXZ"
-// CHECK: store i8* bitcast (void (%"struct.pr20007::A"*)* @"?f at A@pr20007@@QAEXXZ" to i8*)
+// CHECK: store ptr @"?f at A@pr20007@@QAEXXZ"
}
namespace pr20007_kw {
@@ -819,7 +806,7 @@ struct __single_inheritance B;
struct B : public A {};
void test() { void (B::*a)() = &B::f; }
// CHECK-LABEL: define dso_local void @"?test at pr20007_kw@@YAXXZ"
-// CHECK: store i8* bitcast (void (%"struct.pr20007_kw::A"*)* @"?f at A@pr20007_kw@@QAEXXZ" to i8*)
+// CHECK: store ptr @"?f at A@pr20007_kw@@QAEXXZ"
}
namespace pr20007_pragma {
@@ -894,7 +881,7 @@ struct D : A, C {};
typedef void (D::*DMemPtrTy)();
// CHECK-LABEL: define dso_local void @"?get_memptr at pr23878@@YAP8D at 1@AEXXZXZ"
-// CHECK: @"??_9C at pr23878@@$BA at AE" to i8*), i32 0, i32 4
+// CHECK: @"??_9C at pr23878@@$BA at AE", i32 0, i32 4
DMemPtrTy get_memptr() { return &D::f; }
}
@@ -910,7 +897,7 @@ class CA : public C {
// CHECK-LABEL: foo_fun
void foo_fun() {
- // CHECK: store i8* bitcast (void (%class.CA*)* @"?OnHelp at CA@@QAEXXZ" to i8*), i8**
+ // CHECK: store ptr @"?OnHelp at CA@@QAEXXZ", ptr
f func = (f)&CA::OnHelp;
}
namespace PR24703 {
diff --git a/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
index c3a9743dbe804..f9d6473cb6c62 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
struct Left {
virtual void left();
@@ -20,110 +20,93 @@ extern "C" void foo(void *);
void call_left_no_override(ChildNoOverride *child) {
// CHECK-LABEL: define dso_local void @"?call_left_no_override
-// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
+// CHECK: %[[CHILD:.*]] = load ptr
child->left();
// Only need to cast 'this' to Left*.
-// CHECK: %[[LEFT:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to %struct.Left*
-// CHECK: %[[VFPTR:.*]] = bitcast %struct.Left* %[[LEFT]] to void (%struct.Left*)***
-// CHECK: %[[VFTABLE:.*]] = load void (%struct.Left*)**, void (%struct.Left*)*** %[[VFPTR]]
-// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Left*)*, void (%struct.Left*)** %[[VFTABLE]], i64 0
-// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Left*)*, void (%struct.Left*)** %[[VFUN]]
-// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Left* {{[^,]*}} %[[LEFT]])
+// CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[CHILD]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](ptr {{[^,]*}} %[[CHILD]])
// CHECK: ret
}
void ChildOverride::left() {
// CHECK-LABEL: define dso_local x86_thiscallcc void @"?left at ChildOverride@@UAEXXZ"
-// CHECK-SAME: (%struct.ChildOverride* {{[^,]*}} %[[THIS:.*]])
+// CHECK-SAME: (ptr {{[^,]*}} %[[THIS:.*]])
//
// No need to adjust 'this' as the ChildOverride's layout begins with Left.
-// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
-// CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 4
+// CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 4
foo(this);
-// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
-// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
-// CHECK: call void @foo(i8* noundef %[[THIS_i8]])
+// CHECK: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: call void @foo(ptr noundef %[[THIS]])
// CHECK: ret
}
void call_left_override(ChildOverride *child) {
// CHECK-LABEL: define dso_local void @"?call_left_override
-// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
+// CHECK: %[[CHILD:.*]] = load ptr
child->left();
-// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to void (%struct.ChildOverride*)***
-// CHECK: %[[VFTABLE:.*]] = load void (%struct.ChildOverride*)**, void (%struct.ChildOverride*)*** %[[VFPTR]]
-// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFTABLE]], i64 0
-// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFUN]]
+// CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[CHILD]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]
//
-// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.ChildOverride* {{[^,]*}} %[[CHILD]])
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](ptr {{[^,]*}} %[[CHILD]])
// CHECK: ret
}
void call_right_no_override(ChildNoOverride *child) {
// CHECK-LABEL: define dso_local void @"?call_right_no_override
-// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
+// CHECK: %[[CHILD:.*]] = load ptr
child->right();
// When calling a right base's virtual method, one needs to adjust 'this' at
// the caller site.
//
-// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to i8*
-// CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
-// CHECK: %[[RIGHT:.*]] = bitcast i8* %[[RIGHT_i8]] to %struct.Right*
+// CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, ptr %[[CHILD]], i32 4
//
-// CHECK: %[[VFPTR:.*]] = bitcast %struct.Right* %[[RIGHT]] to void (%struct.Right*)***
-// CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)**, void (%struct.Right*)*** %[[VFPTR]]
-// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)*, void (%struct.Right*)** %[[VFTABLE]], i64 0
-// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Right*)*, void (%struct.Right*)** %[[VFUN]]
-// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Right* {{[^,]*}} %[[RIGHT]])
+// CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[RIGHT_i8]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](ptr {{[^,]*}} %[[RIGHT_i8]])
// CHECK: ret
}
void ChildOverride::right() {
-// CHECK-LABEL: define dso_local x86_thiscallcc void @"?right at ChildOverride@@UAEXXZ"(i8*
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"?right at ChildOverride@@UAEXXZ"(ptr
//
// ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we
// need to adjust 'this' before use.
//
-// CHECK: %[[THIS_STORE:.*]] = alloca %struct.ChildOverride*, align 4
-// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
-// CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %[[ECX:.*]] to %struct.ChildOverride*
-// CHECK: store %struct.ChildOverride* %[[COERCE_VAL]], %struct.ChildOverride** %[[THIS_STORE]], align 4
-// CHECK: %[[THIS_INIT:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_STORE]], align 4
-// CHECK: store %struct.ChildOverride* %[[THIS_INIT]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
-// CHECK: %[[THIS_RELOAD:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
-// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS_RELOAD]] to i8*
-// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.ChildOverride*
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 4
+// CHECK: store ptr %[[ECX:.*]], ptr %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -4
foo(this);
-// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
-// CHECK: call void @foo(i8* noundef %[[THIS_PARAM]])
+// CHECK: call void @foo(ptr noundef %[[THIS_ADJUSTED]])
// CHECK: ret
}
void call_right_override(ChildOverride *child) {
// CHECK-LABEL: define dso_local void @"?call_right_override
-// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
+// CHECK: %[[CHILD:.*]] = load ptr
child->right();
// When calling a right child's virtual method, one needs to adjust 'this' at
// the caller site.
//
-// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
-// CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
+// CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, ptr %[[CHILD]], i32 4
//
-// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
-// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
-// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to void (i8*)***
-// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
-// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 0
-// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
+// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[CHILD]], i32 4
+// CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[VFPTR_i8]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]
//
-// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* noundef %[[RIGHT]])
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](ptr noundef %[[RIGHT]])
// CHECK: ret
}
@@ -132,22 +115,15 @@ struct GrandchildOverride : ChildOverride {
};
void GrandchildOverride::right() {
-// CHECK-LABEL: define dso_local x86_thiscallcc void @"?right at GrandchildOverride@@UAEXXZ"(i8*
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"?right at GrandchildOverride@@UAEXXZ"(ptr
//
-// CHECK: %[[THIS_STORE:.*]] = alloca %struct.GrandchildOverride*, align 4
-// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4
-// CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %[[ECX:.*]] to %struct.GrandchildOverride*
-// CHECK: store %struct.GrandchildOverride* %[[COERCE_VAL]], %struct.GrandchildOverride** %[[THIS_STORE]], align 4
-// CHECK: %[[THIS_INIT:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_STORE]], align 4
-// CHECK: store %struct.GrandchildOverride* %[[THIS_INIT]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
-// CHECK: %[[THIS_RELOAD:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
-// CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS_RELOAD]] to i8*
-// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.GrandchildOverride*
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 4
+// CHECK: store ptr %[[ECX:.*]], ptr %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -4
foo(this);
-// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
-// CHECK: call void @foo(i8* noundef %[[THIS_PARAM]])
+// CHECK: call void @foo(ptr noundef %[[THIS_ADJUSTED]])
// CHECK: ret
}
@@ -160,35 +136,29 @@ void emit_ctors() {
Left l;
// CHECK-LABEL: define {{.*}} @"??0Left@@QAE at XZ"
// CHECK-NOT: getelementptr
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7Left@@6B@" to i32 (...)**)
+ // CHECK: store ptr @"??_7Left@@6B@"
// CHECK: ret
Right r;
// CHECK-LABEL: define {{.*}} @"??0Right@@QAE at XZ"
// CHECK-NOT: getelementptr
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7Right@@6B@" to i32 (...)**)
+ // CHECK: store ptr @"??_7Right@@6B@"
// CHECK: ret
ChildOverride co;
// CHECK-LABEL: define {{.*}} @"??0ChildOverride@@QAE at XZ"
- // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
- // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
- // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
- // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: %[[THIS:.*]] = load ptr, ptr
+ // CHECK: store ptr @"??_7ChildOverride@@6BLeft@@@", ptr %[[THIS]]
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 4
+ // CHECK: store ptr @"??_7ChildOverride@@6BRight@@@", ptr %[[VFPTR_i8]]
// CHECK: ret
GrandchildOverride gc;
// CHECK-LABEL: define {{.*}} @"??0GrandchildOverride@@QAE at XZ"
- // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
- // CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
- // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
- // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: %[[THIS:.*]] = load ptr, ptr
+ // CHECK: store ptr @"??_7GrandchildOverride@@6BLeft@@@", ptr %[[THIS]]
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 4
+ // CHECK: store ptr @"??_7GrandchildOverride@@6BRight@@@", ptr %[[VFPTR_i8]]
// CHECK: ret
}
@@ -204,8 +174,8 @@ struct AsymmetricChild : LeftWithNonVirtualDtor, Right {
void call_asymmetric_child_complete_dtor() {
// CHECK-LABEL: define dso_local void @"?call_asymmetric_child_complete_dtor@@YAXXZ"
AsymmetricChild obj;
- // CHECK: call x86_thiscallcc noundef %struct.AsymmetricChild* @"??0AsymmetricChild@@QAE at XZ"(%struct.AsymmetricChild* {{[^,]*}} %[[OBJ:.*]])
+ // CHECK: call x86_thiscallcc noundef ptr @"??0AsymmetricChild@@QAE at XZ"(ptr {{[^,]*}} %[[OBJ:.*]])
// CHECK-NOT: getelementptr
- // CHECK: call x86_thiscallcc void @"??1AsymmetricChild@@UAE at XZ"(%struct.AsymmetricChild* {{[^,]*}} %[[OBJ]])
+ // CHECK: call x86_thiscallcc void @"??1AsymmetricChild@@UAE at XZ"(ptr {{[^,]*}} %[[OBJ]])
// CHECK: ret
}
diff --git a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index 08c9faf6fd774..9d737e3979ddd 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 --check-prefix WIN %s
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA --check-prefix WIN %s
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 --check-prefix WIN %s
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -emit-llvm %s -o - -triple=aarch64-windows-msvc -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA64 --check-prefix WIN %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 --check-prefix WIN %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA --check-prefix WIN %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 --check-prefix WIN %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=aarch64-windows-msvc -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA64 --check-prefix WIN %s
struct Empty {};
@@ -79,8 +79,7 @@ struct SmallWithSmallWithPrivate {
};
// WIN32: declare dso_local void @"{{.*take_bools_and_chars.*}}"
-// WIN32: (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor,
-// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca(<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor, i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>)
+// WIN32: (ptr inalloca(<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor, i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>)
void take_bools_and_chars(char a, char b, SmallWithDtor c, char d, bool e, int f, bool g);
void call_bools_and_chars() {
take_bools_and_chars('A', 'B', SmallWithDtor(), 'D', true, 13, false);
@@ -88,58 +87,58 @@ void call_bools_and_chars() {
// Returning structs that fit into a register.
Small small_return() { return Small(); }
-// LINUX-LABEL: define{{.*}} void @_Z12small_returnv(%struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z12small_returnv(ptr noalias sret(%struct.Small) align 4 %agg.result)
// WIN32: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
// WIN64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
// WOA64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
Medium medium_return() { return Medium(); }
-// LINUX-LABEL: define{{.*}} void @_Z13medium_returnv(%struct.Medium* noalias sret(%struct.Medium) align 4 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z13medium_returnv(ptr noalias sret(%struct.Medium) align 4 %agg.result)
// WIN32: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"()
// WIN64: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"()
// WOA64: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"()
// Returning structs that fit into a register but are not POD.
SmallCpp11NotCpp03Pod small_non_pod_return() { return SmallCpp11NotCpp03Pod(); }
-// LINUX-LABEL: define{{.*}} void @_Z20small_non_pod_returnv(%struct.SmallCpp11NotCpp03Pod* noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
-// WIN32: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
-// WIN64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
-// WOA64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* inreg noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z20small_non_pod_returnv(ptr noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
+// WIN32: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
+// WIN64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
+// WOA64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr inreg noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result)
SmallWithCtor small_with_ctor_return() { return SmallWithCtor(); }
-// LINUX-LABEL: define{{.*}} void @_Z22small_with_ctor_returnv(%struct.SmallWithCtor* noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
-// WIN32: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
-// WIN64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z22small_with_ctor_returnv(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+// WIN32: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+// WIN64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
// FIXME: The 'sret' mark here doesn't seem to be enough to convince LLVM to
// preserve the hidden sret pointer in R0 across the function.
-// WOA: define dso_local arm_aapcs_vfpcc void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
-// WOA64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* inreg noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+// WOA64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr inreg noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
SmallWithDtor small_with_dtor_return() { return SmallWithDtor(); }
-// LINUX-LABEL: define{{.*}} void @_Z22small_with_dtor_returnv(%struct.SmallWithDtor* noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
-// WIN32: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(%struct.SmallWithDtor* noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
-// WIN64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(%struct.SmallWithDtor* noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
-// WOA64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(%struct.SmallWithDtor* inreg noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z22small_with_dtor_returnv(ptr noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
+// WIN32: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
+// WIN64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
+// WOA64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr inreg noalias sret(%struct.SmallWithDtor) align 4 %agg.result)
SmallWithVftable small_with_vftable_return() { return SmallWithVftable(); }
-// LINUX-LABEL: define{{.*}} void @_Z25small_with_vftable_returnv(%struct.SmallWithVftable* noalias sret(%struct.SmallWithVftable) align 4 %agg.result)
-// WIN32: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret(%struct.SmallWithVftable) align 4 %agg.result)
-// WIN64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret(%struct.SmallWithVftable) align 8 %agg.result)
-// WOA64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* inreg noalias sret(%struct.SmallWithVftable) align 8 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z25small_with_vftable_returnv(ptr noalias sret(%struct.SmallWithVftable) align 4 %agg.result)
+// WIN32: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr noalias sret(%struct.SmallWithVftable) align 4 %agg.result)
+// WIN64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr noalias sret(%struct.SmallWithVftable) align 8 %agg.result)
+// WOA64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr inreg noalias sret(%struct.SmallWithVftable) align 8 %agg.result)
MediumWithCopyCtor medium_with_copy_ctor_return() { return MediumWithCopyCtor(); }
-// LINUX-LABEL: define{{.*}} void @_Z28medium_with_copy_ctor_returnv(%struct.MediumWithCopyCtor* noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
-// WIN32: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
-// WIN64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
-// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
-// WOA64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* inreg noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z28medium_with_copy_ctor_returnv(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
+// WIN32: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
+// WIN64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
+// WOA64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr inreg noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result)
// Returning a large struct that doesn't fit into a register.
Big big_return() { return Big(); }
-// LINUX-LABEL: define{{.*}} void @_Z10big_returnv(%struct.Big* noalias sret(%struct.Big) align 4 %agg.result)
-// WIN32: define dso_local void @"?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret(%struct.Big) align 4 %agg.result)
-// WIN64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret(%struct.Big) align 4 %agg.result)
-// WOA64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret(%struct.Big) align 4 %agg.result)
+// LINUX-LABEL: define{{.*}} void @_Z10big_returnv(ptr noalias sret(%struct.Big) align 4 %agg.result)
+// WIN32: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr noalias sret(%struct.Big) align 4 %agg.result)
+// WIN64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr noalias sret(%struct.Big) align 4 %agg.result)
+// WOA64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr noalias sret(%struct.Big) align 4 %agg.result)
void small_arg(Small s) {}
@@ -155,50 +154,50 @@ void medium_arg(Medium s) {}
// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg@@YAXUMedium@@@Z"([2 x i32] %s.coerce)
void base_no_byval_arg(BaseNoByval s) {}
-// LINUX-LABEL: define{{.*}} void @_Z17base_no_byval_arg11BaseNoByval(%struct.BaseNoByval* noundef byval(%struct.BaseNoByval) align 4 %s)
+// LINUX-LABEL: define{{.*}} void @_Z17base_no_byval_arg11BaseNoByval(ptr noundef byval(%struct.BaseNoByval) align 4 %s)
// WIN32: define dso_local void @"?base_no_byval_arg@@YAXUBaseNoByval@@@Z"(i32 %s.0, i32 %s.1)
// WIN64: define dso_local void @"?base_no_byval_arg@@YAXUBaseNoByval@@@Z"(i64 %s.coerce)
// WOA: define dso_local arm_aapcs_vfpcc void @"?base_no_byval_arg@@YAXUBaseNoByval@@@Z"([2 x i32] %s.coerce)
void small_arg_with_ctor(SmallWithCtor s) {}
-// LINUX-LABEL: define{{.*}} void @_Z19small_arg_with_ctor13SmallWithCtor(%struct.SmallWithCtor* noundef byval(%struct.SmallWithCtor) align 4 %s)
+// LINUX-LABEL: define{{.*}} void @_Z19small_arg_with_ctor13SmallWithCtor(ptr noundef byval(%struct.SmallWithCtor) align 4 %s)
// WIN32: define dso_local void @"?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.0)
// WIN64: define dso_local void @"?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.coerce)
// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"([1 x i32] %s.coerce)
// FIXME: We could coerce to a series of i32s here if we wanted to.
void multibyte_arg(Multibyte s) {}
-// LINUX-LABEL: define{{.*}} void @_Z13multibyte_arg9Multibyte(%struct.Multibyte* noundef byval(%struct.Multibyte) align 4 %s)
-// WIN32: define dso_local void @"?multibyte_arg@@YAXUMultibyte@@@Z"(%struct.Multibyte* noundef byval(%struct.Multibyte) align 4 %s)
+// LINUX-LABEL: define{{.*}} void @_Z13multibyte_arg9Multibyte(ptr noundef byval(%struct.Multibyte) align 4 %s)
+// WIN32: define dso_local void @"?multibyte_arg@@YAXUMultibyte@@@Z"(ptr noundef byval(%struct.Multibyte) align 4 %s)
// WIN64: define dso_local void @"?multibyte_arg@@YAXUMultibyte@@@Z"(i32 %s.coerce)
// WOA: define dso_local arm_aapcs_vfpcc void @"?multibyte_arg@@YAXUMultibyte@@@Z"([1 x i32] %s.coerce)
void packed_arg(Packed s) {}
-// LINUX-LABEL: define{{.*}} void @_Z10packed_arg6Packed(%struct.Packed* noundef byval(%struct.Packed) align 4 %s)
-// WIN32: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(%struct.Packed* noundef byval(%struct.Packed) align 4 %s)
-// WIN64: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(%struct.Packed* noundef %s)
+// LINUX-LABEL: define{{.*}} void @_Z10packed_arg6Packed(ptr noundef byval(%struct.Packed) align 4 %s)
+// WIN32: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(ptr noundef byval(%struct.Packed) align 4 %s)
+// WIN64: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(ptr noundef %s)
// Test that dtors are invoked in the callee.
void small_arg_with_dtor(SmallWithDtor s) {}
-// WIN32: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca(<{ %struct.SmallWithDtor }>) %0) {{.*}} {
+// WIN32: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(ptr inalloca(<{ %struct.SmallWithDtor }>) %0) {{.*}} {
// WIN32: call x86_thiscallcc void @"??1SmallWithDtor@@QAE at XZ"
// WIN32: }
// WIN64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %s.coerce) {{.*}} {
// WIN64: call void @"??1SmallWithDtor@@QEAA at XZ"
// WIN64: }
// WOA64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i64 %s.coerce) {{.*}} {
-// WOA64: call void @"??1SmallWithDtor@@QEAA at XZ"(%struct.SmallWithDtor* {{[^,]*}} %s)
+// WOA64: call void @"??1SmallWithDtor@@QEAA at XZ"(ptr {{[^,]*}} %s)
// WOA64: }
// FIXME: MSVC incompatible!
-// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* noundef %s) {{.*}} {
-// WOA: call arm_aapcs_vfpcc void @"??1SmallWithDtor@@QAA at XZ"(%struct.SmallWithDtor* {{[^,]*}} %s)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(ptr noundef %s) {{.*}} {
+// WOA: call arm_aapcs_vfpcc void @"??1SmallWithDtor@@QAA at XZ"(ptr {{[^,]*}} %s)
// WOA: }
// Test that the eligible non-aggregate is passed directly, but returned
// indirectly on ARM64 Windows.
-// WOA64: define dso_local void @"?small_arg_with_private_member@@YA?AUSmallWithPrivate@@U1@@Z"(%struct.SmallWithPrivate* inreg noalias sret(%struct.SmallWithPrivate) align 4 %agg.result, i64 %s.coerce) {{.*}} {
+// WOA64: define dso_local void @"?small_arg_with_private_member@@YA?AUSmallWithPrivate@@U1@@Z"(ptr inreg noalias sret(%struct.SmallWithPrivate) align 4 %agg.result, i64 %s.coerce) {{.*}} {
SmallWithPrivate small_arg_with_private_member(SmallWithPrivate s) { return s; }
// WOA64: define dso_local i32 @"?small_arg_with_small_struct_with_private_member@@YA?AUSmallWithSmallWithPrivate@@U1@@Z"(i64 %s.coerce) {{.*}} {
@@ -209,19 +208,19 @@ void call_small_arg_with_dtor() {
small_arg_with_dtor(SmallWithDtor());
}
// WIN64-LABEL: define dso_local void @"?call_small_arg_with_dtor@@YAXXZ"()
-// WIN64: call noundef %struct.SmallWithDtor* @"??0SmallWithDtor@@QEAA at XZ"
+// WIN64: call noundef ptr @"??0SmallWithDtor@@QEAA at XZ"
// WIN64: call void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %{{.*}})
// WIN64: ret void
// Test that references aren't destroyed in the callee.
void ref_small_arg_with_dtor(const SmallWithDtor &s) { }
-// WIN32: define dso_local void @"?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"(%struct.SmallWithDtor* noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %s) {{.*}} {
+// WIN32: define dso_local void @"?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %s) {{.*}} {
// WIN32-NOT: call x86_thiscallcc void @"??1SmallWithDtor@@QAE at XZ"
// WIN32: }
-// WIN64-LABEL: define dso_local void @"?ref_small_arg_with_dtor@@YAXAEBUSmallWithDtor@@@Z"(%struct.SmallWithDtor* noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %s)
+// WIN64-LABEL: define dso_local void @"?ref_small_arg_with_dtor@@YAXAEBUSmallWithDtor@@@Z"(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %s)
void big_arg_with_dtor(BigWithDtor s) {}
-// WIN64-LABEL: define dso_local void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(%struct.BigWithDtor* noundef %s)
+// WIN64-LABEL: define dso_local void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(ptr noundef %s)
// WIN64: call void @"??1BigWithDtor@@QEAA at XZ"
// WIN64: }
@@ -231,8 +230,8 @@ void call_big_arg_with_dtor() {
// We can elide the copy of the temporary in the caller, because this object is
// larger than 8 bytes and is passed indirectly.
// WIN64-LABEL: define dso_local void @"?call_big_arg_with_dtor@@YAXXZ"()
-// WIN64: call noundef %struct.BigWithDtor* @"??0BigWithDtor@@QEAA at XZ"
-// WIN64: call void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(%struct.BigWithDtor* noundef %{{.*}})
+// WIN64: call noundef ptr @"??0BigWithDtor@@QEAA at XZ"
+// WIN64: call void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(ptr noundef %{{.*}})
// WIN64-NOT: call void @"??1BigWithDtor@@QEAA at XZ"
// WIN64: ret void
@@ -241,7 +240,7 @@ void temporary_ref_with_dtor() {
ref_small_arg_with_dtor(SmallWithDtor());
}
// WIN32: define dso_local void @"?temporary_ref_with_dtor@@YAXXZ"() {{.*}} {
-// WIN32: call x86_thiscallcc noundef %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE at XZ"
+// WIN32: call x86_thiscallcc noundef ptr @"??0SmallWithDtor@@QAE at XZ"
// WIN32: call void @"?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"
// WIN32: call x86_thiscallcc void @"??1SmallWithDtor@@QAE at XZ"
// WIN32: }
@@ -253,29 +252,29 @@ void eh_cleanup_arg_with_dtor() {
// When exceptions are off, we don't have any cleanups. See
// microsoft-abi-exceptions.cpp for these cleanups.
// WIN32: define dso_local void @"?eh_cleanup_arg_with_dtor@@YAXXZ"() {{.*}} {
-// WIN32: call x86_thiscallcc noundef %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE at XZ"
-// WIN32: call x86_thiscallcc noundef %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE at XZ"
+// WIN32: call x86_thiscallcc noundef ptr @"??0SmallWithDtor@@QAE at XZ"
+// WIN32: call x86_thiscallcc noundef ptr @"??0SmallWithDtor@@QAE at XZ"
// WIN32: call void @"?takes_two_by_val_with_dtor@@YAXUSmallWithDtor@@0 at Z"
// WIN32-NOT: call x86_thiscallcc void @"??1SmallWithDtor@@QAE at XZ"
// WIN32: }
void small_arg_with_vftable(SmallWithVftable s) {}
-// LINUX-LABEL: define{{.*}} void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* noundef %s)
-// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca(<{ %struct.SmallWithVftable }>) %0)
-// WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* noundef %s)
-// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* noundef %s)
+// LINUX-LABEL: define{{.*}} void @_Z22small_arg_with_vftable16SmallWithVftable(ptr noundef %s)
+// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr inalloca(<{ %struct.SmallWithVftable }>) %0)
+// WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr noundef %s)
+// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr noundef %s)
void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
-// LINUX-LABEL: define{{.*}} void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* noundef %s)
-// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca(<{ %struct.MediumWithCopyCtor }>) %0)
-// WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* noundef %s)
-// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* noundef %s)
-// WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* noundef %s)
+// LINUX-LABEL: define{{.*}} void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(ptr noundef %s)
+// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr inalloca(<{ %struct.MediumWithCopyCtor }>) %0)
+// WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr noundef %s)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr noundef %s)
+// WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr noundef %s)
void big_arg(Big s) {}
-// LINUX-LABEL: define{{.*}} void @_Z7big_arg3Big(%struct.Big* noundef byval(%struct.Big) align 4 %s)
-// WIN32: define dso_local void @"?big_arg@@YAXUBig@@@Z"(%struct.Big* noundef byval(%struct.Big) align 4 %s)
-// WIN64: define dso_local void @"?big_arg@@YAXUBig@@@Z"(%struct.Big* noundef %s)
+// LINUX-LABEL: define{{.*}} void @_Z7big_arg3Big(ptr noundef byval(%struct.Big) align 4 %s)
+// WIN32: define dso_local void @"?big_arg@@YAXUBig@@@Z"(ptr noundef byval(%struct.Big) align 4 %s)
+// WIN64: define dso_local void @"?big_arg@@YAXUBig@@@Z"(ptr noundef %s)
// PR27607: We would attempt to load i32 value out of the reference instead of
// just loading the pointer from the struct during argument expansion.
@@ -284,8 +283,8 @@ struct RefField {
int &x;
};
void takes_ref_field(RefField s) {}
-// LINUX-LABEL: define{{.*}} void @_Z15takes_ref_field8RefField(%struct.RefField* noundef byval(%struct.RefField) align 4 %s)
-// WIN32: define dso_local void @"?takes_ref_field@@YAXURefField@@@Z"(i32* %s.0)
+// LINUX-LABEL: define{{.*}} void @_Z15takes_ref_field8RefField(ptr noundef byval(%struct.RefField) align 4 %s)
+// WIN32: define dso_local void @"?takes_ref_field@@YAXURefField@@@Z"(ptr %s.0)
// WIN64: define dso_local void @"?takes_ref_field@@YAXURefField@@@Z"(i64 %s.coerce)
void pass_ref_field() {
@@ -293,61 +292,61 @@ void pass_ref_field() {
takes_ref_field(RefField(x));
}
// LINUX-LABEL: define{{.*}} void @_Z14pass_ref_fieldv()
-// LINUX: call void @_Z15takes_ref_field8RefField(%struct.RefField* noundef byval(%struct.RefField) align 4 %{{.*}})
+// LINUX: call void @_Z15takes_ref_field8RefField(ptr noundef byval(%struct.RefField) align 4 %{{.*}})
// WIN32-LABEL: define dso_local void @"?pass_ref_field@@YAXXZ"()
-// WIN32: call void @"?takes_ref_field@@YAXURefField@@@Z"(i32* %{{.*}})
+// WIN32: call void @"?takes_ref_field@@YAXURefField@@@Z"(ptr %{{.*}})
// WIN64-LABEL: define dso_local void @"?pass_ref_field@@YAXXZ"()
// WIN64: call void @"?takes_ref_field@@YAXURefField@@@Z"(i64 %{{.*}})
class Class {
public:
Small thiscall_method_small() { return Small(); }
- // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(%struct.Small* noalias sret(%struct.Small) align 4 %agg.result, %class.Class* {{[^,]*}} %this)
- // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small at Class@@QAE?AUSmall@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
- // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small at Class@@QEAA?AUSmall@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
- // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small at Class@@QEAA?AUSmall@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Small* inreg noalias sret(%struct.Small) align 4 %agg.result)
+ // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(ptr noalias sret(%struct.Small) align 4 %agg.result, ptr {{[^,]*}} %this)
+ // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small at Class@@QAE?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small at Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result)
+ // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small at Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr inreg noalias sret(%struct.Small) align 4 %agg.result)
SmallWithCtor thiscall_method_small_with_ctor() { return SmallWithCtor(); }
- // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(%struct.SmallWithCtor* noalias sret(%struct.SmallWithCtor) align 4 %agg.result, %class.Class* {{[^,]*}} %this)
- // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small_with_ctor at Class@@QAE?AUSmallWithCtor@@XZ"(%class.Class* {{[^,]*}} %this, %struct.SmallWithCtor* noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
- // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor at Class@@QEAA?AUSmallWithCtor@@XZ"(%class.Class* {{[^,]*}} %this, %struct.SmallWithCtor* noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
- // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor at Class@@QEAA?AUSmallWithCtor@@XZ"(%class.Class* {{[^,]*}} %this, %struct.SmallWithCtor* inreg noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+ // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result, ptr {{[^,]*}} %this)
+ // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small_with_ctor at Class@@QAE?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor at Class@@QEAA?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
+ // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor at Class@@QEAA?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr inreg noalias sret(%struct.SmallWithCtor) align 4 %agg.result)
Small __cdecl cdecl_method_small() { return Small(); }
- // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(%struct.Small* noalias sret(%struct.Small) align 4 %agg.result, %class.Class* {{[^,]*}} %this)
- // WIN32: define {{.*}} void @"?cdecl_method_small at Class@@QAA?AUSmall@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
- // WIN64: define linkonce_odr dso_local void @"?cdecl_method_small at Class@@QEAA?AUSmall@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Small* noalias sret(%struct.Small) align 4 %agg.result)
+ // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(ptr noalias sret(%struct.Small) align 4 %agg.result, ptr {{[^,]*}} %this)
+ // WIN32: define {{.*}} void @"?cdecl_method_small at Class@@QAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?cdecl_method_small at Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result)
Big __cdecl cdecl_method_big() { return Big(); }
- // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(%struct.Big* noalias sret(%struct.Big) align 4 %agg.result, %class.Class* {{[^,]*}} %this)
- // WIN32: define {{.*}} void @"?cdecl_method_big at Class@@QAA?AUBig@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Big* noalias sret(%struct.Big) align 4 %agg.result)
- // WIN64: define linkonce_odr dso_local void @"?cdecl_method_big at Class@@QEAA?AUBig@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Big* noalias sret(%struct.Big) align 4 %agg.result)
- // WOA64: define linkonce_odr dso_local void @"?cdecl_method_big at Class@@QEAA?AUBig@@XZ"(%class.Class* {{[^,]*}} %this, %struct.Big* inreg noalias sret(%struct.Big) align 4 %agg.result)
+ // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(ptr noalias sret(%struct.Big) align 4 %agg.result, ptr {{[^,]*}} %this)
+ // WIN32: define {{.*}} void @"?cdecl_method_big at Class@@QAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Big) align 4 %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?cdecl_method_big at Class@@QEAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Big) align 4 %agg.result)
+ // WOA64: define linkonce_odr dso_local void @"?cdecl_method_big at Class@@QEAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr inreg noalias sret(%struct.Big) align 4 %agg.result)
void thiscall_method_arg(Empty s) {}
- // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Empty(%class.Class* {{[^,]*}} %this)
- // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUEmpty@@@Z"(%class.Class* {{[^,]*}} %this, %struct.Empty* noundef byval(%struct.Empty) align 4 %s)
- // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUEmpty@@@Z"(%class.Class* {{[^,]*}} %this, i8 %s.coerce)
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Empty(ptr {{[^,]*}} %this)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUEmpty@@@Z"(ptr {{[^,]*}} %this, ptr noundef byval(%struct.Empty) align 4 %s)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUEmpty@@@Z"(ptr {{[^,]*}} %this, i8 %s.coerce)
void thiscall_method_arg(EmptyWithCtor s) {}
- // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13EmptyWithCtor(%class.Class* {{[^,]*}} %this)
- // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUEmptyWithCtor@@@Z"(%class.Class* {{[^,]*}} %this, %struct.EmptyWithCtor* noundef byval(%struct.EmptyWithCtor) align 4 %s)
- // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUEmptyWithCtor@@@Z"(%class.Class* {{[^,]*}} %this, i8 %s.coerce)
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13EmptyWithCtor(ptr {{[^,]*}} %this)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUEmptyWithCtor@@@Z"(ptr {{[^,]*}} %this, ptr noundef byval(%struct.EmptyWithCtor) align 4 %s)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUEmptyWithCtor@@@Z"(ptr {{[^,]*}} %this, i8 %s.coerce)
void thiscall_method_arg(Small s) {}
- // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* {{[^,]*}} %this, i32 %s.0)
- // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUSmall@@@Z"(%class.Class* {{[^,]*}} %this, i32 %s.0)
- // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUSmall@@@Z"(%class.Class* {{[^,]*}} %this, i32 %s.coerce)
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(ptr {{[^,]*}} %this, i32 %s.0)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUSmall@@@Z"(ptr {{[^,]*}} %this, i32 %s.0)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUSmall@@@Z"(ptr {{[^,]*}} %this, i32 %s.coerce)
void thiscall_method_arg(SmallWithCtor s) {}
- // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13SmallWithCtor(%class.Class* {{[^,]*}} %this, %struct.SmallWithCtor* noundef byval(%struct.SmallWithCtor) align 4 %s)
- // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUSmallWithCtor@@@Z"(%class.Class* {{[^,]*}} %this, i32 %s.0)
- // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUSmallWithCtor@@@Z"(%class.Class* {{[^,]*}} %this, i32 %s.coerce)
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13SmallWithCtor(ptr {{[^,]*}} %this, ptr noundef byval(%struct.SmallWithCtor) align 4 %s)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUSmallWithCtor@@@Z"(ptr {{[^,]*}} %this, i32 %s.0)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUSmallWithCtor@@@Z"(ptr {{[^,]*}} %this, i32 %s.coerce)
void thiscall_method_arg(Big s) {}
- // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE3Big(%class.Class* {{[^,]*}} %this, %struct.Big* noundef byval(%struct.Big) align 4 %s)
- // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUBig@@@Z"(%class.Class* {{[^,]*}} %this, %struct.Big* noundef byval(%struct.Big) align 4 %s)
- // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUBig@@@Z"(%class.Class* {{[^,]*}} %this, %struct.Big* noundef %s)
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE3Big(ptr {{[^,]*}} %this, ptr noundef byval(%struct.Big) align 4 %s)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg at Class@@QAEXUBig@@@Z"(ptr {{[^,]*}} %this, ptr noundef byval(%struct.Big) align 4 %s)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg at Class@@QEAAXUBig@@@Z"(ptr {{[^,]*}} %this, ptr noundef %s)
};
void use_class() {
@@ -371,8 +370,8 @@ struct X {
};
void g(X) {
}
-// WIN32: define dso_local void @"?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca(<{ %struct.X, [3 x i8] }>) %0) {{.*}} {
-// WIN32: call x86_thiscallcc void @"??1X@@QAE at XZ"(%struct.X* {{.*}})
+// WIN32: define dso_local void @"?g@@YAXUX@@@Z"(ptr inalloca(<{ %struct.X, [3 x i8] }>) %0) {{.*}} {
+// WIN32: call x86_thiscallcc void @"??1X@@QAE at XZ"(ptr {{.*}})
// WIN32: }
void f() {
g(X());
@@ -402,11 +401,11 @@ void bar() {
}
// WIN32-LABEL: define dso_local void @"?bar at test2@@YAXXZ"() {{.*}} {
// WIN32: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty:<{ %"struct.test2::NonTrivial", %"struct.test2::POD" }>]]
-// WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32: getelementptr inbounds [[argmem_ty]], ptr %[[argmem]], i32 0, i32 1
// WIN32: call void @llvm.memcpy
-// WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0
-// WIN32: call x86_thiscallcc noundef %"struct.test2::NonTrivial"* @"??0NonTrivial at test2@@QAE at XZ"
-// WIN32: call noundef i32 @"?foo at test2@@YAHUNonTrivial at 1@UPOD at 1@@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %argmem)
+// WIN32: getelementptr inbounds [[argmem_ty]], ptr %[[argmem]], i32 0, i32 0
+// WIN32: call x86_thiscallcc noundef ptr @"??0NonTrivial at test2@@QAE at XZ"
+// WIN32: call noundef i32 @"?foo at test2@@YAHUNonTrivial at 1@UPOD at 1@@Z"(ptr inalloca([[argmem_ty]]) %argmem)
// WIN32: ret void
// WIN32: }
@@ -422,7 +421,7 @@ struct NonTrivial {
int a;
};
void foo(NonTrivial a, bool b) { }
-// WIN32-LABEL: define dso_local void @"?foo at test3@@YAXUNonTrivial at 1@_N at Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>) %0)
+// WIN32-LABEL: define dso_local void @"?foo at test3@@YAXUNonTrivial at 1@_N at Z"(ptr inalloca(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>) %0)
}
@@ -438,20 +437,17 @@ struct ForwardDeclare1 {};
void fn2(FnPtr1 a, SmallWithDtor b) { fn1(a, b); };
// WIN32-LABEL: define dso_local void @"?fn2@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"
-// WIN32: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]], [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]]* %{{.*}}, i32 0, i32 0
-// WIN32: %[[a1:[^ ]*]] = bitcast {}** %[[a]] to void [[dst_ty:\(%struct.ForwardDeclare1\*\)\*]]*
-// WIN32: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]]
-// WIN32: %[[gep1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
-// WIN32: %[[bc1:[^ ]*]] = bitcast %struct.SmallWithDtor* %[[gep1]] to i8*
-// WIN32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %[[bc1]], i8* align 4 {{.*}}, i32 4, i1 false)
-// WIN32: %[[a2:[^ ]*]] = load void [[dst_ty]], void [[dst_ty]]* %[[a1]], align 4
-// WIN32: %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0
-// WIN32: %[[addr:[^ ]*]] = bitcast {}** %[[gep2]] to void [[dst_ty]]*
-// WIN32: store void [[dst_ty]] %[[a2]], void [[dst_ty]]* %[[addr]], align 4
-// WIN32: call void @"?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %[[argmem]])
+// WIN32: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty:<{ ptr, %struct.SmallWithDtor }>]], ptr %{{.*}}, i32 0, i32 0
+// WIN32: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty:<{ ptr, %struct.SmallWithDtor }>]]
+// WIN32: %[[gep1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], ptr %[[argmem]], i32 0, i32 1
+// WIN32: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[gep1]], ptr align 4 {{.*}}, i32 4, i1 false)
+// WIN32: %[[a2:[^ ]*]] = load ptr, ptr %[[a]], align 4
+// WIN32: %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], ptr %[[argmem]], i32 0, i32 0
+// WIN32: store ptr %[[a2]], ptr %[[gep2]], align 4
+// WIN32: call void @"?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"(ptr inalloca([[argmem_ty]]) %[[argmem]])
namespace pr30293 {
-// Virtual methods living in a secondary vtable take i8* as their 'this'
+// Virtual methods living in a secondary vtable take ptr as their 'this'
// parameter because the 'this' parameter on entry points to the secondary
// vptr. We used to have a bug where we didn't apply this rule consistently,
// and it would cause assertion failures when used with inalloca.
@@ -468,13 +464,13 @@ struct C final : A, B {
};
void C::g() { return h(SmallWithDtor()); }
-// WIN32-LABEL: define dso_local x86_thiscallcc void @"?g at C@pr30293@@QAEXXZ"(%"struct.pr30293::C"* {{[^,]*}} %this)
-// WIN32: call x86_thiscallcc noundef %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE at XZ"
-// WIN32: call void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>) %{{[^,)]*}})
-// WIN32: declare dso_local void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>))
+// WIN32-LABEL: define dso_local x86_thiscallcc void @"?g at C@pr30293@@QAEXXZ"(ptr {{[^,]*}} %this)
+// WIN32: call x86_thiscallcc noundef ptr @"??0SmallWithDtor@@QAE at XZ"
+// WIN32: call void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(ptr inalloca(<{ ptr, %struct.SmallWithDtor }>) %{{[^,)]*}})
+// WIN32: declare dso_local void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(ptr inalloca(<{ ptr, %struct.SmallWithDtor }>))
-// WIN64-LABEL: define dso_local void @"?g at C@pr30293@@QEAAXXZ"(%"struct.pr30293::C"* {{[^,]*}} %this)
-// WIN64: declare dso_local void @"?h at C@pr30293@@UEAAXUSmallWithDtor@@@Z"(i8* noundef, i32)
+// WIN64-LABEL: define dso_local void @"?g at C@pr30293@@QEAAXXZ"(ptr {{[^,]*}} %this)
+// WIN64: declare dso_local void @"?h at C@pr30293@@UEAAXUSmallWithDtor@@@Z"(ptr noundef, i32)
}
namespace protected_member_of_member {
diff --git a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
index 676d345da1f22..07abc3d065e5e 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -emit-llvm -fno-rtti %s -std=c++11 -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-rtti > %t
+// RUN: %clang_cc1 -no-enable-noundef-analysis -emit-llvm -fno-rtti %s -std=c++11 -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-rtti > %t
// RUN: FileCheck %s < %t
// vftables are emitted very late, so do another pass to try to keep the checks
// in source order.
@@ -7,7 +7,7 @@
// RUN: FileCheck --check-prefix DTORS3 %s < %t
// RUN: FileCheck --check-prefix DTORS4 %s < %t
//
-// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti -std=c++11 | FileCheck --check-prefix DTORS-X64 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti -std=c++11 | FileCheck --check-prefix DTORS-X64 %s
namespace basic {
@@ -20,11 +20,11 @@ class A {
void no_constructor_destructor_infinite_recursion() {
A a;
-// CHECK: define linkonce_odr dso_local x86_thiscallcc %"class.basic::A"* @"??0A at basic@@QAE at XZ"(%"class.basic::A"* {{[^,]*}} returned {{[^,]*}} %this) {{.*}} comdat {{.*}} {
-// CHECK: [[THIS_ADDR:%[.0-9A-Z_a-z]+]] = alloca %"class.basic::A"*, align 4
-// CHECK-NEXT: store %"class.basic::A"* %this, %"class.basic::A"** [[THIS_ADDR]], align 4
-// CHECK-NEXT: [[T1:%[.0-9A-Z_a-z]+]] = load %"class.basic::A"*, %"class.basic::A"** [[THIS_ADDR]]
-// CHECK-NEXT: ret %"class.basic::A"* [[T1]]
+// CHECK: define linkonce_odr dso_local x86_thiscallcc ptr @"??0A at basic@@QAE at XZ"(ptr {{[^,]*}} returned {{[^,]*}} %this) {{.*}} comdat {{.*}} {
+// CHECK: [[THIS_ADDR:%[.0-9A-Z_a-z]+]] = alloca ptr, align 4
+// CHECK-NEXT: store ptr %this, ptr [[THIS_ADDR]], align 4
+// CHECK-NEXT: [[T1:%[.0-9A-Z_a-z]+]] = load ptr, ptr [[THIS_ADDR]]
+// CHECK-NEXT: ret ptr [[T1]]
// CHECK-NEXT: }
}
@@ -41,28 +41,27 @@ struct B {
// Tests that we can define constructors outside the class (PR12784).
B::B() {
- // CHECK: define dso_local x86_thiscallcc %"struct.basic::B"* @"??0B at basic@@QAE at XZ"(%"struct.basic::B"* {{[^,]*}} returned {{[^,]*}} %this)
+ // CHECK: define dso_local x86_thiscallcc ptr @"??0B at basic@@QAE at XZ"(ptr {{[^,]*}} returned {{[^,]*}} %this)
// CHECK: ret
}
struct C {
virtual ~C() {
-// DTORS: define linkonce_odr dso_local x86_thiscallcc i8* @"??_GC at basic@@UAEPAXI at Z"(%"struct.basic::C"* {{[^,]*}} %this, i32 %should_call_delete) {{.*}} comdat {{.*}} {
-// DTORS: store i32 %should_call_delete, i32* %[[SHOULD_DELETE_VAR:[0-9a-z._]+]], align 4
-// DTORS: store i8* %{{.*}}, i8** %[[RETVAL:[0-9a-z._]+]]
-// DTORS: %[[SHOULD_DELETE_VALUE:[0-9a-z._]+]] = load i32, i32* %[[SHOULD_DELETE_VAR]]
-// DTORS: call x86_thiscallcc void @"??1C at basic@@UAE at XZ"(%"struct.basic::C"* {{[^,]*}} %[[THIS:[0-9a-z]+]])
+// DTORS: define linkonce_odr dso_local x86_thiscallcc ptr @"??_GC at basic@@UAEPAXI at Z"(ptr {{[^,]*}} %this, i32 %should_call_delete) {{.*}} comdat {{.*}} {
+// DTORS: store i32 %should_call_delete, ptr %[[SHOULD_DELETE_VAR:[0-9a-z._]+]], align 4
+// DTORS: store ptr %{{.*}}, ptr %[[RETVAL:retval]]
+// DTORS: %[[SHOULD_DELETE_VALUE:[0-9a-z._]+]] = load i32, ptr %[[SHOULD_DELETE_VAR]]
+// DTORS: call x86_thiscallcc void @"??1C at basic@@UAE at XZ"(ptr {{[^,]*}} %[[THIS:[0-9a-z]+]])
// DTORS-NEXT: %[[CONDITION:[0-9]+]] = icmp eq i32 %[[SHOULD_DELETE_VALUE]], 0
// DTORS-NEXT: br i1 %[[CONDITION]], label %[[CONTINUE_LABEL:[0-9a-z._]+]], label %[[CALL_DELETE_LABEL:[0-9a-z._]+]]
//
// DTORS: [[CALL_DELETE_LABEL]]
-// DTORS-NEXT: %[[THIS_AS_VOID:[0-9a-z]+]] = bitcast %"struct.basic::C"* %[[THIS]] to i8*
-// DTORS-NEXT: call void @"??3 at YAXPAX@Z"(i8* %[[THIS_AS_VOID]])
+// DTORS-NEXT: call void @"??3 at YAXPAX@Z"(ptr %[[THIS]])
// DTORS-NEXT: br label %[[CONTINUE_LABEL]]
//
// DTORS: [[CONTINUE_LABEL]]
-// DTORS-NEXT: %[[RET:.*]] = load i8*, i8** %[[RETVAL]]
-// DTORS-NEXT: ret i8* %[[RET]]
+// DTORS-NEXT: %[[RET:.*]] = load ptr, ptr %[[RETVAL]]
+// DTORS-NEXT: ret ptr %[[RET]]
// Check that we do the mangling correctly on x64.
// DTORS-X64: @"??_GC at basic@@UEAAPEAXI at Z"
@@ -76,50 +75,46 @@ 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 i32 (...)***
-// CHECK: store i32 (...)** bitcast ({ [2 x i8*] }* @"??_7C at basic@@6B@" to i32 (...)**), i32 (...)*** [[THIS_PTR]]
+// CHECK: store ptr @"??_7C at basic@@6B@", ptr {{.*}}
}
void call_complete_dtor(C *obj_ptr) {
-// CHECK: define dso_local void @"?call_complete_dtor at basic@@YAXPAUC at 1@@Z"(%"struct.basic::C"* %obj_ptr)
+// CHECK: define dso_local void @"?call_complete_dtor at basic@@YAXPAUC at 1@@Z"(ptr %obj_ptr)
obj_ptr->~C();
-// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4
-// CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)***
-// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]]
-// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0
-// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]]
-// CHECK-NEXT: call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 0)
+// CHECK: %[[OBJ_PTR_VALUE:.*]] = load ptr, ptr %{{.*}}, align 4
+// CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[OBJ_PTR_VALUE]]
+// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
+// CHECK-NEXT: %[[VDTOR:.*]] = load ptr, ptr %[[PVDTOR]]
+// CHECK-NEXT: call x86_thiscallcc ptr %[[VDTOR]](ptr {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 0)
// CHECK-NEXT: ret void
}
void call_deleting_dtor(C *obj_ptr) {
-// CHECK: define dso_local void @"?call_deleting_dtor at basic@@YAXPAUC at 1@@Z"(%"struct.basic::C"* %obj_ptr)
+// CHECK: define dso_local void @"?call_deleting_dtor at basic@@YAXPAUC at 1@@Z"(ptr %obj_ptr)
delete obj_ptr;
-// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4
+// CHECK: %[[OBJ_PTR_VALUE:.*]] = load ptr, ptr %{{.*}}, align 4
// CHECK: br i1 {{.*}}, label %[[DELETE_NULL:.*]], label %[[DELETE_NOTNULL:.*]]
// CHECK: [[DELETE_NOTNULL]]
-// CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)***
-// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]]
-// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0
-// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]]
-// CHECK-NEXT: call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 1)
+// CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[OBJ_PTR_VALUE]]
+// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
+// CHECK-NEXT: %[[VDTOR:.*]] = load ptr, ptr %[[PVDTOR]]
+// CHECK-NEXT: call x86_thiscallcc ptr %[[VDTOR]](ptr {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 1)
// CHECK: ret void
}
void call_deleting_dtor_and_global_delete(C *obj_ptr) {
-// CHECK: define dso_local void @"?call_deleting_dtor_and_global_delete at basic@@YAXPAUC at 1@@Z"(%"struct.basic::C"* %obj_ptr)
+// CHECK: define dso_local void @"?call_deleting_dtor_and_global_delete at basic@@YAXPAUC at 1@@Z"(ptr %obj_ptr)
::delete obj_ptr;
-// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4
+// CHECK: %[[OBJ_PTR_VALUE:.*]] = load ptr, ptr %{{.*}}, align 4
// CHECK: br i1 {{.*}}, label %[[DELETE_NULL:.*]], label %[[DELETE_NOTNULL:.*]]
// CHECK: [[DELETE_NOTNULL]]
-// CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)***
-// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]]
-// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0
-// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]]
-// CHECK-NEXT: %[[CALL:.*]] = call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 0)
-// CHECK-NEXT: call void @"??3 at YAXPAX@Z"(i8* %[[CALL]])
+// CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[OBJ_PTR_VALUE]]
+// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
+// CHECK-NEXT: %[[VDTOR:.*]] = load ptr, ptr %[[PVDTOR]]
+// CHECK-NEXT: %[[CALL:.*]] = call x86_thiscallcc ptr %[[VDTOR]](ptr {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 0)
+// CHECK-NEXT: call void @"??3 at YAXPAX@Z"(ptr %[[CALL]])
// CHECK: ret void
}
@@ -155,26 +150,24 @@ struct C : A, B {
};
C::~C() {
-// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1C at dtor_in_second_nvbase@@UAE at XZ"(i8*{{[^,]*}} %this.coerce)
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1C at dtor_in_second_nvbase@@UAE at XZ"(ptr{{[^,]*}} %this)
// No this adjustment!
// CHECK-NOT: getelementptr
-// CHECK: load %"struct.dtor_in_second_nvbase::C"*, %"struct.dtor_in_second_nvbase::C"** %{{.*}}
+// CHECK: load ptr, ptr %{{.*}}
// Now we this-adjust before calling ~B.
-// CHECK: bitcast %"struct.dtor_in_second_nvbase::C"* %{{.*}} to i8*
-// CHECK: getelementptr inbounds i8, i8* %{{.*}}, i32 4
-// CHECK: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::B"*
-// CHECK: call x86_thiscallcc void @"??1B at dtor_in_second_nvbase@@UAE at XZ"(%"struct.dtor_in_second_nvbase::B"*{{[^,]*}} %{{.*}})
+// CHECK: getelementptr inbounds i8, ptr %{{.*}}, i32 4
+// CHECK: call x86_thiscallcc void @"??1B at dtor_in_second_nvbase@@UAE at XZ"(ptr{{[^,]*}} %{{.*}})
// CHECK: ret void
}
void foo() {
C c;
}
-// DTORS2-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_EC at dtor_in_second_nvbase@@W3AEPAXI at Z"(i8* %this.coerce, i32 %should_call_delete)
+// DTORS2-LABEL: define linkonce_odr dso_local x86_thiscallcc ptr @"??_EC at dtor_in_second_nvbase@@W3AEPAXI at Z"(ptr %this, i32 %should_call_delete)
// Do an adjustment from B* to C*.
-// DTORS2: getelementptr i8, i8* %{{.*}}, i32 -4
-// DTORS2: %[[CALL:.*]] = tail call x86_thiscallcc i8* @"??_GC at dtor_in_second_nvbase@@UAEPAXI at Z"
-// DTORS2: ret i8* %[[CALL]]
+// DTORS2: getelementptr i8, ptr %{{.*}}, i32 -4
+// DTORS2: %[[CALL:.*]] = tail call x86_thiscallcc ptr @"??_GC at dtor_in_second_nvbase@@UAEPAXI at Z"
+// DTORS2: ret ptr %[[CALL]]
}
namespace test2 {
@@ -191,12 +184,11 @@ struct E : virtual C { int e; };
struct F : D, E { ~F(); int f; };
F::~F() {
-// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1F at test2@@UAE at XZ"(i8*{{[^,]*}})
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1F at test2@@UAE at XZ"(ptr{{[^,]*}})
// Do an adjustment from C vbase subobject to F as though F was the
// complete type.
-// CHECK: getelementptr inbounds i8, i8* %{{.*}}, i32 -20
-// CHECK: bitcast i8* %{{.*}} to %"struct.test2::F"*
-// CHECK: store %"struct.test2::F"*
+// CHECK: getelementptr inbounds i8, ptr %{{.*}}, i32 -20
+// CHECK: store ptr
}
void foo() {
@@ -204,7 +196,7 @@ void foo() {
}
// DTORS3-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??_DF at test2@@QAEXXZ"({{.*}} {{.*}} comdat
// Do an adjustment from C* to F*.
-// DTORS3: getelementptr i8, i8* %{{.*}}, i32 20
+// DTORS3: getelementptr i8, ptr %{{.*}}, i32 20
// DTORS3: call x86_thiscallcc void @"??1F at test2@@UAE at XZ"
// DTORS3: ret void
@@ -222,8 +214,8 @@ struct B : A {
};
B::B() {
- // CHECK: define dso_local x86_thiscallcc %"struct.constructors::B"* @"??0B at constructors@@QAE at XZ"(%"struct.constructors::B"* {{[^,]*}} returned {{[^,]*}} %this)
- // CHECK: call x86_thiscallcc %"struct.constructors::A"* @"??0A at constructors@@QAE at XZ"(%"struct.constructors::A"* {{[^,]*}} %{{.*}})
+ // CHECK: define dso_local x86_thiscallcc ptr @"??0B at constructors@@QAE at XZ"(ptr {{[^,]*}} returned {{[^,]*}} %this)
+ // CHECK: call x86_thiscallcc ptr @"??0A at constructors@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
// CHECK: ret
}
@@ -232,22 +224,18 @@ struct C : virtual A {
};
C::C() {
- // CHECK: define dso_local x86_thiscallcc %"struct.constructors::C"* @"??0C at constructors@@QAE at XZ"(%"struct.constructors::C"* {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived)
+ // CHECK: define dso_local x86_thiscallcc ptr @"??0C at constructors@@QAE at XZ"(ptr {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived)
// TODO: make sure this works in the Release build too;
- // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
- // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // CHECK: store i32 %is_most_derived, ptr %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, ptr %[[IS_MOST_DERIVED_VAR]]
// CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
// CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
//
// CHECK: [[INIT_VBASES]]
- // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::C"* %{{.*}} to i8*
- // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 0
- // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
- // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8C at constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]]
- // CHECK-NEXT: bitcast %"struct.constructors::C"* %{{.*}} to i8*
- // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i32 4
- // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
- // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"??0A at constructors@@QAE at XZ"(%"struct.constructors::A"* {{[^,]*}} %{{.*}})
+ // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 0
+ // CHECK-NEXT: store ptr @"??_8C at constructors@@7B@", ptr %[[vbptr_off]]
+ // CHECK-NEXT: getelementptr inbounds i8, ptr %{{.*}}, i32 4
+ // CHECK-NEXT: call x86_thiscallcc ptr @"??0A at constructors@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
// CHECK-NEXT: br label %[[SKIP_VBASES]]
//
// CHECK: [[SKIP_VBASES]]
@@ -259,7 +247,7 @@ C::C() {
void create_C() {
C c;
// CHECK: define dso_local void @"?create_C at constructors@@YAXXZ"()
- // CHECK: call x86_thiscallcc %"struct.constructors::C"* @"??0C at constructors@@QAE at XZ"(%"struct.constructors::C"* {{[^,]*}} %c, i32 1)
+ // CHECK: call x86_thiscallcc ptr @"??0C at constructors@@QAE at XZ"(ptr {{[^,]*}} %c, i32 1)
// CHECK: ret
}
@@ -268,25 +256,21 @@ struct D : C {
};
D::D() {
- // CHECK: define dso_local x86_thiscallcc %"struct.constructors::D"* @"??0D at constructors@@QAE at XZ"(%"struct.constructors::D"* {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived) unnamed_addr
- // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
- // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // CHECK: define dso_local x86_thiscallcc ptr @"??0D at constructors@@QAE at XZ"(ptr {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived) unnamed_addr
+ // CHECK: store i32 %is_most_derived, ptr %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, ptr %[[IS_MOST_DERIVED_VAR]]
// CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
// CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
//
// CHECK: [[INIT_VBASES]]
- // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::D"* %{{.*}} to i8*
- // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 0
- // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
- // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8D at constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]]
- // CHECK-NEXT: bitcast %"struct.constructors::D"* %{{.*}} to i8*
- // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i32 4
- // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
- // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"??0A at constructors@@QAE at XZ"(%"struct.constructors::A"* {{[^,]*}} %{{.*}})
+ // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 0
+ // CHECK-NEXT: store ptr @"??_8D at constructors@@7B@", ptr %[[vbptr_off]]
+ // CHECK-NEXT: getelementptr inbounds i8, ptr %{{.*}}, i32 4
+ // CHECK-NEXT: call x86_thiscallcc ptr @"??0A at constructors@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
// CHECK-NEXT: br label %[[SKIP_VBASES]]
//
// CHECK: [[SKIP_VBASES]]
- // CHECK: call x86_thiscallcc %"struct.constructors::C"* @"??0C at constructors@@QAE at XZ"(%"struct.constructors::C"* {{[^,]*}} %{{.*}}, i32 0)
+ // CHECK: call x86_thiscallcc ptr @"??0C at constructors@@QAE at XZ"(ptr {{[^,]*}} %{{.*}}, i32 0)
// CHECK: ret
}
@@ -295,25 +279,20 @@ struct E : virtual C {
};
E::E() {
- // CHECK: define dso_local x86_thiscallcc %"struct.constructors::E"* @"??0E at constructors@@QAE at XZ"(%"struct.constructors::E"* {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived) unnamed_addr
- // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
- // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // CHECK: define dso_local x86_thiscallcc ptr @"??0E at constructors@@QAE at XZ"(ptr {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived) unnamed_addr
+ // CHECK: store i32 %is_most_derived, ptr %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, ptr %[[IS_MOST_DERIVED_VAR]]
// CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
// CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
//
// CHECK: [[INIT_VBASES]]
- // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::E"* %{{.*}} to i8*
- // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 0
- // CHECK-NEXT: %[[vbptr_E:.*]] = bitcast i8* %[[offs]] to i32**
- // CHECK-NEXT: store i32* getelementptr inbounds ([3 x i32], [3 x i32]* @"??_8E at constructors@@7B01@@", i32 0, i32 0), i32** %[[vbptr_E]]
- // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 4
- // CHECK-NEXT: %[[vbptr_C:.*]] = bitcast i8* %[[offs]] to i32**
- // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8E at constructors@@7BC at 1@@", i32 0, i32 0), i32** %[[vbptr_C]]
- // CHECK-NEXT: bitcast %"struct.constructors::E"* %{{.*}} to i8*
- // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i32 4
- // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
- // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"??0A at constructors@@QAE at XZ"(%"struct.constructors::A"* {{[^,]*}} %{{.*}})
- // CHECK: call x86_thiscallcc %"struct.constructors::C"* @"??0C at constructors@@QAE at XZ"(%"struct.constructors::C"* {{[^,]*}} %{{.*}}, i32 0)
+ // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 0
+ // CHECK-NEXT: store ptr @"??_8E at constructors@@7B01@@", ptr %[[offs]]
+ // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 4
+ // CHECK-NEXT: store ptr @"??_8E at constructors@@7BC at 1@@", ptr %[[offs]]
+ // CHECK-NEXT: getelementptr inbounds i8, ptr %{{.*}}, i32 4
+ // CHECK-NEXT: call x86_thiscallcc ptr @"??0A at constructors@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
+ // CHECK: call x86_thiscallcc ptr @"??0C at constructors@@QAE at XZ"(ptr {{[^,]*}} %{{.*}}, i32 0)
// CHECK-NEXT: br label %[[SKIP_VBASES]]
//
// CHECK: [[SKIP_VBASES]]
@@ -327,7 +306,7 @@ struct F {
};
F::F() {}
-// CHECK: define dso_local x86_thiscallcc %"struct.constructors::F"* @"??0F at constructors@@QAE at XZ"
+// CHECK: define dso_local x86_thiscallcc ptr @"??0F at constructors@@QAE at XZ"
} // end namespace constructors
@@ -355,7 +334,7 @@ struct D : B, C { ~D(); };
void call_vbase_complete(D *d) {
d->~D();
// CHECK: define dso_local void @"?call_vbase_complete at dtors@@YAXPAUD at 1@@Z"
-// CHECK: call x86_thiscallcc void @"??_DD at dtors@@QAEXXZ"(%"struct.dtors::D"* {{[^,]*}} %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"??_DD at dtors@@QAEXXZ"(ptr {{[^,]*}} %{{[^,]+}})
// CHECK: ret
}
@@ -371,7 +350,7 @@ void call_vbase_complete(D *d) {
void destroy_d_complete() {
D d;
// CHECK: define dso_local void @"?destroy_d_complete at dtors@@YAXXZ"
-// CHECK: call x86_thiscallcc void @"??_DD at dtors@@QAEXXZ"(%"struct.dtors::D"* {{[^,]*}} %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"??_DD at dtors@@QAEXXZ"(ptr {{[^,]*}} %{{[^,]+}})
// CHECK: ret
}
@@ -381,7 +360,7 @@ void destroy_d_complete() {
void call_nv_deleting_dtor(D *d) {
delete d;
// CHECK: define dso_local void @"?call_nv_deleting_dtor at dtors@@YAXPAUD at 1@@Z"
-// CHECK: call x86_thiscallcc void @"??_DD at dtors@@QAEXXZ"(%"struct.dtors::D"* {{[^,]*}} %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"??_DD at dtors@@QAEXXZ"(ptr {{[^,]*}} %{{[^,]+}})
// CHECK: call void @"??3 at YAXPAX@Z"
// CHECK: ret
}
@@ -398,12 +377,12 @@ struct B : virtual A {
B::B(int *a) {}
B::B(const char *a, ...) {}
B::B(short *a) {}
-// CHECK: define dso_local x86_thiscallcc %"struct.test1::B"* @"??0B at test1@@QAE at PAH@Z"
-// CHECK: (%"struct.test1::B"* {{[^,]*}} returned {{[^,]*}} %this, i32* %a, i32 %is_most_derived)
-// CHECK: define dso_local %"struct.test1::B"* @"??0B at test1@@QAA at PBDZZ"
-// CHECK: (%"struct.test1::B"* {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived, i8* %a, ...)
-// CHECK: define dso_local x86_thiscallcc %"struct.test1::B"* @"??0B at test1@@QAE at PAF@Z"
-// CHECK: (%"struct.test1::B"* {{[^,]*}} returned {{[^,]*}} %this, i16* %a, i32 %is_most_derived)
+// CHECK: define dso_local x86_thiscallcc ptr @"??0B at test1@@QAE at PAH@Z"
+// CHECK: (ptr {{[^,]*}} returned {{[^,]*}} %this, ptr %a, i32 %is_most_derived)
+// CHECK: define dso_local ptr @"??0B at test1@@QAA at PBDZZ"
+// CHECK: (ptr {{[^,]*}} returned {{[^,]*}} %this, i32 %is_most_derived, ptr %a, ...)
+// CHECK: define dso_local x86_thiscallcc ptr @"??0B at test1@@QAE at PAF@Z"
+// CHECK: (ptr {{[^,]*}} returned {{[^,]*}} %this, ptr %a, i32 %is_most_derived)
void construct_b() {
int a;
@@ -411,10 +390,10 @@ void construct_b() {
B b2("%d %d", 1, 2);
}
// CHECK-LABEL: define dso_local void @"?construct_b at test1@@YAXXZ"()
-// CHECK: call x86_thiscallcc %"struct.test1::B"* @"??0B at test1@@QAE at PAH@Z"
-// CHECK: (%"struct.test1::B"* {{.*}}, i32* {{.*}}, i32 1)
-// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...) @"??0B at test1@@QAA at PBDZZ"
-// CHECK: (%"struct.test1::B"* {{.*}}, i32 1, i8* {{.*}}, i32 1, i32 2)
+// CHECK: call x86_thiscallcc ptr @"??0B at test1@@QAE at PAH@Z"
+// CHECK: (ptr {{.*}}, ptr {{.*}}, i32 1)
+// CHECK: call ptr (ptr, i32, ptr, ...) @"??0B at test1@@QAA at PBDZZ"
+// CHECK: (ptr {{.*}}, i32 1, ptr {{.*}}, i32 1, i32 2)
}
namespace implicit_copy_vtable {
@@ -445,11 +424,11 @@ struct X : virtual Y {
};
X::X(int) : X() {}
}
-// CHECK: define dso_local x86_thiscallcc %"struct.delegating_ctor::X"* @"??0X at delegating_ctor@@QAE at H@Z"(
+// CHECK: define dso_local x86_thiscallcc ptr @"??0X at delegating_ctor@@QAE at H@Z"(
// CHECK: %[[is_most_derived_addr:.*]] = alloca i32, align 4
-// CHECK: store i32 %is_most_derived, i32* %[[is_most_derived_addr]]
-// CHECK: %[[is_most_derived:.*]] = load i32, i32* %[[is_most_derived_addr]]
-// CHECK: call x86_thiscallcc {{.*}}* @"??0X at delegating_ctor@@QAE at XZ"({{.*}} i32 %[[is_most_derived]])
+// CHECK: store i32 %is_most_derived, ptr %[[is_most_derived_addr]]
+// CHECK: %[[is_most_derived:.*]] = load i32, ptr %[[is_most_derived_addr]]
+// CHECK: call x86_thiscallcc ptr @"??0X at delegating_ctor@@QAE at XZ"({{.*}} i32 %[[is_most_derived]])
// Dtor thunks for classes in anonymous namespaces should be internal, not
// linkonce_odr.
@@ -461,17 +440,17 @@ struct A {
void *getA() {
return (void*)new A();
}
-// CHECK: define internal x86_thiscallcc i8* @"??_GA@?A0x{{[^@]*}}@@UAEPAXI at Z"
-// CHECK: (%"struct.(anonymous namespace)::A"* {{[^,]*}} %this, i32 %should_call_delete)
+// CHECK: define internal x86_thiscallcc ptr @"??_GA@?A0x{{[^@]*}}@@UAEPAXI at Z"
+// CHECK: (ptr {{[^,]*}} %this, i32 %should_call_delete)
// CHECK: define internal x86_thiscallcc void @"??1A@?A0x{{[^@]*}}@@UAE at XZ"
-// CHECK: (%"struct.(anonymous namespace)::A"* {{[^,]*}} %this)
+// CHECK: (ptr {{[^,]*}} %this)
// Check that we correctly transform __stdcall to __thiscall for ctors and
// dtors.
class G {
public:
__stdcall G() {};
-// DTORS4: define linkonce_odr dso_local x86_thiscallcc %class.G* @"??0G@@QAE at XZ"
+// DTORS4: define linkonce_odr dso_local x86_thiscallcc ptr @"??0G@@QAE at XZ"
__stdcall ~G() {};
// DTORS4: define linkonce_odr dso_local x86_thiscallcc void @"??1G@@QAE at XZ"
};
diff --git a/clang/test/CodeGenCXX/microsoft-abi-this-nullable.cpp b/clang/test/CodeGenCXX/microsoft-abi-this-nullable.cpp
index b0c60f05bceae..e0523f4cf4d1e 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-this-nullable.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-this-nullable.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -no-opaque-pointers -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -no-opaque-pointers -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-delete-null-pointer-checks | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-delete-null-pointer-checks | FileCheck %s
struct Left {
virtual void left();
@@ -20,7 +20,7 @@ struct ChildOverride : Left, Right {
extern "C" void foo(void *);
void call_left_no_override(ChildNoOverride *child) {
- // CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
+ // CHECK: %[[CHILD:.*]] = load ptr
child->left();
}
@@ -30,13 +30,10 @@ void call_right_no_override(ChildNoOverride *child) {
child->right();
// When calling a right base's virtual method, one needs to adjust `this` at the caller site.
//
- // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to i8*
- // CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
- // CHECK: %[[RIGHT:.*]] = bitcast i8* %[[RIGHT_i8]] to %struct.Right*
+ // CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, ptr %[[CHILD]], i32 4
//
- // CHECK: %[[VFPTR:.*]] = bitcast %struct.Right* %[[RIGHT]] to void (%struct.Right*)***
- // CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)**, void (%struct.Right*)*** %[[VFPTR]]
- // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)*, void (%struct.Right*)** %[[VFTABLE]], i64 0
+ // CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[RIGHT_i8]]
+ // CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
}
void ChildOverride::right() {
@@ -47,7 +44,7 @@ void call_right_override(ChildOverride *child) {
child->right();
// Ensure that `nonnull` and `dereferenceable(N)` are not emitted whether or not null is valid
//
- // CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
- // CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
- // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* noundef %[[RIGHT]])
+ // CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, ptr %[[CHILD]], i32 4
+ // CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]
+ // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](ptr noundef %[[RIGHT]])
}
diff --git a/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp b/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
index 88eab9489938a..38aa81253ccad 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -no-opaque-pointers -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 >%t 2>&1
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 >%t 2>&1
// RUN: FileCheck --check-prefix=MANGLING %s < %t
// RUN: FileCheck --check-prefix=XMANGLING %s < %t
// RUN: FileCheck --check-prefix=CODEGEN %s < %t
-// RUN: %clang_cc1 -no-opaque-pointers -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s
void foo(void *);
@@ -61,15 +61,15 @@ struct C : A, B {
C::C() {} // Emits vftable and forces thunk generation.
-// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef i8* @"??_EC@@W3AEPAXI at Z"(%struct.C* noundef %this, i32 noundef %should_call_delete) {{.*}} comdat
-// CODEGEN: getelementptr i8, i8* {{.*}}, i32 -4
+// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_EC@@W3AEPAXI at Z"(ptr noundef %this, i32 noundef %should_call_delete) {{.*}} comdat
+// CODEGEN: getelementptr i8, ptr {{.*}}, i32 -4
// FIXME: should actually call _EC, not _GC.
-// CODEGEN: call x86_thiscallcc noundef i8* @"??_GC@@UAEPAXI at Z"
+// CODEGEN: call x86_thiscallcc noundef ptr @"??_GC@@UAEPAXI at Z"
// CODEGEN: ret
-// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?public_f at C@@W3AEXXZ"(%struct.C*
-// CODEGEN: getelementptr i8, i8* {{.*}}, i32 -4
-// CODEGEN: call x86_thiscallcc void @"?public_f at C@@UAEXXZ"(%struct.C*
+// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?public_f at C@@W3AEXXZ"(ptr
+// CODEGEN: getelementptr i8, ptr {{.*}}, i32 -4
+// CODEGEN: call x86_thiscallcc void @"?public_f at C@@UAEXXZ"(ptr
// CODEGEN: ret
void zoo(C* obj) {
@@ -91,9 +91,9 @@ struct E : D {
E::E() {} // Emits vftable and forces thunk generation.
-// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc noundef %struct.C* @"?goo at E@@QAEPAUB@@XZ"{{.*}} comdat
-// CODEGEN: call x86_thiscallcc noundef %struct.C* @"?goo at E@@UAEPAUC@@XZ"
-// CODEGEN: getelementptr inbounds i8, i8* {{.*}}, i32 4
+// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc noundef ptr @"?goo at E@@QAEPAUB@@XZ"{{.*}} comdat
+// CODEGEN: call x86_thiscallcc noundef ptr @"?goo at E@@UAEPAUC@@XZ"
+// CODEGEN: getelementptr inbounds i8, ptr {{.*}}, i32 4
// CODEGEN: ret
struct F : virtual A, virtual B {
@@ -124,18 +124,15 @@ struct I : D {
I::I() {} // Emits vftable and forces thunk generation.
-// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc noundef %struct.{{[BF]}}* @"?goo at I@@QAEPAUB@@XZ"{{.*}} comdat
-// CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc noundef %struct.F* @"?goo at I@@UAEPAUF@@XZ"
-// CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8*
-// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ORIG_RET_i8]], i32 4
-// CODEGEN: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32**
-// CODEGEN: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR]]
-// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 2
-// CODEGEN: %[[VBASE_OFFSET:.*]] = load i32, i32* %[[VBASE_OFFSET_PTR]]
-// CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8, i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
-// CODEGEN: %[[RES:.*]] = bitcast i8* %[[RES_i8]] to %struct.F*
-// CODEGEN: phi %struct.F* {{.*}} %[[RES]]
-// CODEGEN: ret %struct.{{[BF]}}*
+// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc noundef ptr @"?goo at I@@QAEPAUB@@XZ"{{.*}} comdat
+// CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc noundef ptr @"?goo at I@@UAEPAUF@@XZ"
+// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[ORIG_RET]], i32 4
+// CODEGEN: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR_i8]]
+// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 2
+// CODEGEN: %[[VBASE_OFFSET:.*]] = load i32, ptr %[[VBASE_OFFSET_PTR]]
+// CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8, ptr %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
+// CODEGEN: phi ptr {{.*}} %[[RES_i8]]
+// CODEGEN: ret ptr
namespace CrashOnThunksForAttributedType {
// We used to crash on this because the type of foo is an AttributedType, not
@@ -160,5 +157,5 @@ struct E : D {
E::E() {}
E e;
// Class with internal linkage has internal linkage thunks.
-// CODEGEN: define internal x86_thiscallcc noundef %struct.C* @"?goo at E@?A0x{{[^@]*}}@@QAEPAUB@@XZ"
+// CODEGEN: define internal x86_thiscallcc noundef ptr @"?goo at E@?A0x{{[^@]*}}@@QAEPAUB@@XZ"
}
diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
index 5b50353db583e..691fccf9930af 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -no-opaque-pointers %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
// For now, just make sure x86_64 doesn't crash.
-// RUN: %clang_cc1 -no-opaque-pointers %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
struct A {
virtual void f();
@@ -25,28 +25,22 @@ D::D() {} // Forces vftable emission.
// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f at D@@$4PPPPPPPM at A@AEXXZ"
// Note that the vtordisp is applied before really adjusting to D*.
-// CHECK: %[[COERCE_LOAD:.*]] = load %struct.D*, %struct.D** %{{.*}}
-// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
-// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
-// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4
-// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
-// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]]
+// CHECK: %[[ECX:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, ptr %[[ECX]], i32 -4
+// CHECK: %[[VTORDISP:.*]] = load i32, ptr %[[VTORDISP_PTR_i8]]
// CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
-// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
-// CHECK: call x86_thiscallcc void @"?f at D@@UAEXXZ"(i8* noundef %[[ADJUSTED_i8]])
+// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, ptr %[[ECX]], i32 %[[VTORDISP_NEG]]
+// CHECK: call x86_thiscallcc void @"?f at D@@UAEXXZ"(ptr noundef %[[ADJUSTED_i8]])
// CHECK: ret void
// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f at D@@$4PPPPPPPI at 3AEXXZ"
-// CHECK: %[[COERCE_LOAD:.*]] = load %struct.D*, %struct.D** %{{.*}}
-// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
-// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
-// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -8
-// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
-// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]]
+// CHECK: %[[ECX:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, ptr %[[ECX]], i32 -8
+// CHECK: %[[VTORDISP:.*]] = load i32, ptr %[[VTORDISP_PTR_i8]]
// CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
-// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
-// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[VTORDISP_ADJUSTED_i8]], i32 -4
-// CHECK: call x86_thiscallcc void @"?f at D@@UAEXXZ"(i8* noundef %[[ADJUSTED_i8]])
+// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, ptr %[[ECX]], i32 %[[VTORDISP_NEG]]
+// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, ptr %[[VTORDISP_ADJUSTED_i8]], i32 -4
+// CHECK: call x86_thiscallcc void @"?f at D@@UAEXXZ"(ptr noundef %[[ADJUSTED_i8]])
// CHECK: ret void
struct E : virtual A {
@@ -66,21 +60,17 @@ struct G : virtual F, virtual E {
G::G() {} // Forces vftable emission.
-// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f at E@@$R4BA at M@PPPPPPPM at 7AEXXZ"(i8*
-// CHECK: %[[COERCE_LOAD:.*]] = load %struct.E*, %struct.E** %{{.*}}
-// CHECK: %[[ECX:.*]] = load %struct.E*, %struct.E** %{{.*}}
-// CHECK: %[[ECX_i8:.*]] = bitcast %struct.E* %[[ECX]] to i8*
-// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4
-// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
-// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]]
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f at E@@$R4BA at M@PPPPPPPM at 7AEXXZ"(ptr
+// CHECK: %[[ECX:.*]] = load ptr, ptr %{{.*}}
+// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, ptr %[[ECX]], i32 -4
+// CHECK: %[[VTORDISP:.*]] = load i32, ptr %[[VTORDISP_PTR_i8]]
// CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
-// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
-// CHECK: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[VTORDISP_ADJUSTED_i8]], i32 -16
-// CHECK: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32**
-// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR]]
-// CHECK: %[[VBOFFSET_PTR:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 3
-// CHECK: %[[VBASE_OFFSET:.*]] = load i32, i32* %[[VBOFFSET_PTR]]
-// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
-// CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %[[VBASE]], i32 8
-// CHECK: call x86_thiscallcc void @"?f at E@@UAEXXZ"(i8* noundef %[[ARG_i8]])
+// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, ptr %[[ECX]], i32 %[[VTORDISP_NEG]]
+// CHECK: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[VTORDISP_ADJUSTED_i8]], i32 -16
+// CHECK: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR_i8]]
+// CHECK: %[[VBOFFSET_PTR:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 3
+// CHECK: %[[VBASE_OFFSET:.*]] = load i32, ptr %[[VBOFFSET_PTR]]
+// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, ptr %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
+// CHECK: %[[ARG_i8:.*]] = getelementptr i8, ptr %[[VBASE]], i32 8
+// CHECK: call x86_thiscallcc void @"?f at E@@UAEXXZ"(ptr noundef %[[ARG_i8]])
// CHECK: ret void
diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index f52a6cdb6fdeb..5726c483e5382 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -no-opaque-pointers %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=i386-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=i386-pc-win32 -emit-llvm -o %t
// RUN: FileCheck %s < %t
// RUN: FileCheck --check-prefix=CHECK2 %s < %t
// For now, just make sure x86_64 doesn't crash.
-// RUN: %clang_cc1 -no-opaque-pointers %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=x86_64-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=x86_64-pc-win32 -emit-llvm -o %t
struct VBase {
virtual ~VBase();
@@ -20,32 +20,26 @@ struct B : virtual VBase {
};
B::B() {
- // CHECK-LABEL: define dso_local x86_thiscallcc noundef %struct.B* @"??0B@@QAE at XZ"
- // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B**
+ // CHECK-LABEL: define dso_local x86_thiscallcc noundef ptr @"??0B@@QAE at XZ"
+ // CHECK: %[[THIS:.*]] = load ptr, ptr
// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
// Don't check the INIT_VBASES case as it's covered by the ctor tests.
// CHECK: %[[SKIP_VBASES]]
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 0
// ...
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
- // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 %{{.*}}
+ // CHECK: store ptr @"??_7B@@6B@", ptr %[[VFPTR_i8]]
// Initialize vtorDisp:
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 0
// ...
// CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
// CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
- // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
- // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
- // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
+ // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 %[[VBASE_OFFSET]]
+ // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, ptr %[[VBASE_i8]], i32 -4
+ // CHECK: store i32 %[[VTORDISP_VAL]], ptr %[[VTORDISP_i8]]
// CHECK: ret
}
@@ -53,174 +47,138 @@ B::B() {
B::~B() {
// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1B@@UAE at XZ"
// Store initial this:
- // CHECK: %[[THIS:.*]] = alloca %struct.B*
- // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
- // CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
+ // CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+ // CHECK: store ptr %{{.*}}, ptr %[[THIS_ADDR]], align 4
// Reload and adjust the this parameter:
- // CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
- // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
- // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
- // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
+ // CHECK: %[[THIS_RELOAD:.*]] = load ptr, ptr %[[THIS_ADDR]]
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -8
// Restore the vfptr that could have been changed by a subclass.
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[THIS_ADJ_i8]], i32 0
// ...
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
- // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_ADJ_i8]], i32 %{{.*}}
+ // CHECK: store ptr @"??_7B@@6B@", ptr %[[VFPTR_i8]]
// Initialize vtorDisp:
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[THIS_ADJ_i8]], i32 0
// ...
// CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
// CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
- // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
- // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
- // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
- // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
+ // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_ADJ_i8]], i32 %[[VBASE_OFFSET]]
+ // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, ptr %[[VBASE_i8]], i32 -4
+ // CHECK: store i32 %[[VTORDISP_VAL]], ptr %[[VTORDISP_i8]]
foo(); // Avoid the "trivial destructor" optimization.
// CHECK: ret
- // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B*
- // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}}
- // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8
- // CHECK2: call x86_thiscallcc void @"??1B@@UAE at XZ"(i8*{{[^,]*}} %[[B_i8]])
- // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 8
- // CHECK2: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
- // CHECK2: call x86_thiscallcc void @"??1VBase@@UAE at XZ"(%struct.VBase* {{[^,]*}} %[[VBASE]])
+ // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??_DB@@QAEXXZ"(ptr
+ // CHECK2: %[[THIS:.*]] = load ptr, ptr {{.*}}
+ // CHECK2: %[[B_i8:.*]] = getelementptr i8, ptr %[[THIS]], i32 8
+ // CHECK2: call x86_thiscallcc void @"??1B@@UAE at XZ"(ptr{{[^,]*}} %[[B_i8]])
+ // CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 8
+ // CHECK2: call x86_thiscallcc void @"??1VBase@@UAE at XZ"(ptr {{[^,]*}} %[[VBASE_i8]])
// CHECK2: ret
- // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef i8* @"??_GB@@UAEPAXI at Z"
- // CHECK2: store %struct.B* %{{.*}}, %struct.B** %[[THIS:.*]], align 4
- // CHECK2: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR:.*]], align 4
- // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
- // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
- // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8
- // CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
- // CHECK2: call x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B* {{[^,]*}} %[[THIS]])
+ // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_GB@@UAEPAXI at Z"
+ // CHECK2: store ptr %{{.*}}, ptr %[[THIS_ADDR:.*]], align 4
+ // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_PARAM_i8:.*]], i32 -8
+ // CHECK2: call x86_thiscallcc void @"??_DB@@QAEXXZ"(ptr {{[^,]*}} %[[THIS_i8]])
// ...
// CHECK2: ret
}
void B::foo() {
-// CHECK-LABEL: define dso_local x86_thiscallcc void @"?foo at B@@UAEXXZ"(i8*
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"?foo at B@@UAEXXZ"(ptr
//
// B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we
// need to adjust 'this' before use.
//
// Coerce this to correct type:
-// CHECK: %[[THIS_STORE:.*]] = alloca %struct.B*
-// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
-// CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %{{.*}} to %struct.B*
-// CHECK: store %struct.B* %[[COERCE_VAL]], %struct.B** %[[THIS_STORE]], align 4
+// CHECK: %[[THIS_ADDR:.*]] = alloca ptr
//
// Store initial this:
-// CHECK: %[[THIS_INIT:.*]] = load %struct.B*, %struct.B** %[[THIS_STORE]]
-// CHECK: store %struct.B* %[[THIS_INIT]], %struct.B** %[[THIS_ADDR]], align 4
+// CHECK: store ptr {{.*}}, ptr %[[THIS_ADDR]], align 4
//
// Reload and adjust the this parameter:
-// CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
-// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
-// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
-// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
+// CHECK: %[[THIS_RELOAD:.*]] = load ptr, ptr %[[THIS_ADDR]]
+// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -8
field = 42;
-// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
-// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
-// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
-// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
-// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[THIS_ADJ_i8]], i32 0
+// CHECK: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, ptr %[[VBENTRY]]
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
-// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
-// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 %[[VBOFFSET]]
-// CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
-// CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase, %struct.VBase* %[[VBASE]], i32 0, i32 1
-// CHECK: store i32 42, i32* %[[FIELD]], align 4
+// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_ADJ_i8]], i32 %[[VBOFFSET]]
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase, ptr %[[VBASE_i8]], i32 0, i32 1
+// CHECK: store i32 42, ptr %[[FIELD]], align 4
//
// CHECK: ret void
}
void call_vbase_bar(B *obj) {
-// CHECK-LABEL: define dso_local void @"?call_vbase_bar@@YAXPAUB@@@Z"(%struct.B* noundef %obj)
-// CHECK: %[[OBJ:.*]] = load %struct.B
+// CHECK-LABEL: define dso_local void @"?call_vbase_bar@@YAXPAUB@@@Z"(ptr noundef %obj)
+// CHECK: %[[OBJ:.*]] = load ptr
obj->bar();
// When calling a vbase's virtual method, one needs to adjust 'this'
// at the caller site.
//
-// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
-// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
-// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
-// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
-// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 0
+// CHECK: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, ptr %[[VBENTRY]]
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
-// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
+// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 %[[VBOFFSET]]
//
-// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
-// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
-// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
-// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
-// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 0
+// CHECK: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, ptr %[[VBENTRY]]
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
-// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
-// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to void (i8*)***
-// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
-// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 2
-// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
+// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 %[[VBOFFSET]]
+// CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[VBASE_i8]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 2
+// CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]
//
-// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* noundef %[[VBASE]])
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](ptr noundef %[[VBASE]])
//
// CHECK: ret void
}
void delete_B(B *obj) {
-// CHECK-LABEL: define dso_local void @"?delete_B@@YAXPAUB@@@Z"(%struct.B* noundef %obj)
-// CHECK: %[[OBJ:.*]] = load %struct.B
+// CHECK-LABEL: define dso_local void @"?delete_B@@YAXPAUB@@@Z"(ptr noundef %obj)
+// CHECK: %[[OBJ:.*]] = load ptr
delete obj;
-// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
-// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
-// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
-// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
-// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 0
+// CHECK: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, ptr %[[VBENTRY]]
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
-// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
+// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 %[[VBOFFSET]]
//
-// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
-// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
-// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
-// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
-// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 0
+// CHECK: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, ptr %[[VBENTRY]]
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
-// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
-// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to i8* (i8*, i32)***
-// CHECK: %[[VFTABLE:.*]] = load i8* (i8*, i32)**, i8* (i8*, i32)*** %[[VFPTR]]
-// CHECK: %[[VFUN:.*]] = getelementptr inbounds i8* (i8*, i32)*, i8* (i8*, i32)** %[[VFTABLE]], i64 0
-// CHECK: %[[VFUN_VALUE:.*]] = load i8* (i8*, i32)*, i8* (i8*, i32)** %[[VFUN]]
+// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 %[[VBOFFSET]]
+// CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[VBASE_i8]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]
//
-// CHECK: call x86_thiscallcc noundef i8* %[[VFUN_VALUE]](i8* {{[^,]*}} %[[VBASE]], i32 noundef 1)
+// CHECK: call x86_thiscallcc noundef ptr %[[VFUN_VALUE]](ptr {{[^,]*}} %[[VBASE]], i32 noundef 1)
// CHECK: ret void
}
void call_complete_dtor() {
// CHECK-LABEL: define dso_local void @"?call_complete_dtor@@YAXXZ"
B b;
- // CHECK: call x86_thiscallcc noundef %struct.B* @"??0B@@QAE at XZ"(%struct.B* {{[^,]*}} %[[B:.*]], i32 noundef 1)
+ // CHECK: call x86_thiscallcc noundef ptr @"??0B@@QAE at XZ"(ptr {{[^,]*}} %[[B:.*]], i32 noundef 1)
// CHECK-NOT: getelementptr
- // CHECK: call x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B* {{[^,]*}} %[[B]])
+ // CHECK: call x86_thiscallcc void @"??_DB@@QAEXXZ"(ptr {{[^,]*}} %[[B]])
// CHECK: ret
}
@@ -231,7 +189,7 @@ struct C : B {
// Used to crash on an assertion.
C::C() {
-// CHECK-LABEL: define dso_local x86_thiscallcc noundef %struct.C* @"??0C@@QAE at XZ"
+// CHECK-LABEL: define dso_local x86_thiscallcc noundef ptr @"??0C@@QAE at XZ"
}
namespace multiple_vbases {
@@ -255,15 +213,15 @@ struct D : virtual A, virtual B, virtual C {
};
D::D() {
- // CHECK-LABEL: define dso_local x86_thiscallcc noundef %"struct.multiple_vbases::D"* @"??0D at multiple_vbases@@QAE at XZ"
+ // CHECK-LABEL: define dso_local x86_thiscallcc noundef ptr @"??0D at multiple_vbases@@QAE at XZ"
// Just make sure we emit 3 vtordisps after initializing vfptrs.
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D at multiple_vbases@@6BA at 1@@" to i32 (...)**), i32 (...)*** %{{.*}}
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D at multiple_vbases@@6BB at 1@@" to i32 (...)**), i32 (...)*** %{{.*}}
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D at multiple_vbases@@6BC at 1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+ // CHECK: store ptr @"??_7D at multiple_vbases@@6BA at 1@@", ptr %{{.*}}
+ // CHECK: store ptr @"??_7D at multiple_vbases@@6BB at 1@@", ptr %{{.*}}
+ // CHECK: store ptr @"??_7D at multiple_vbases@@6BC at 1@@", ptr %{{.*}}
// ...
- // CHECK: store i32 %{{.*}}, i32* %{{.*}}
- // CHECK: store i32 %{{.*}}, i32* %{{.*}}
- // CHECK: store i32 %{{.*}}, i32* %{{.*}}
+ // CHECK: store i32 %{{.*}}, ptr %{{.*}}
+ // CHECK: store i32 %{{.*}}, ptr %{{.*}}
+ // CHECK: store i32 %{{.*}}, ptr %{{.*}}
// CHECK: ret
}
}
@@ -295,29 +253,21 @@ struct D : virtual Z, B, C {
} d;
D::~D() {
- // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1D at diamond@@UAE at XZ"(i8*{{.*}})
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1D at diamond@@UAE at XZ"(ptr{{.*}})
// Store initial this:
- // CHECK: %[[THIS:.*]] = alloca %"struct.diamond::D"*
- // CHECK: %[[THIS_ADDR:.*]] = alloca %"struct.diamond::D"*
- // CHECK: store %"struct.diamond::D"* %{{.*}}, %"struct.diamond::D"** %[[THIS_ADDR]], align 4
+ // CHECK: %[[THIS_ADDR:.*]] = alloca ptr
+ // CHECK: store ptr %{{.*}}, ptr %[[THIS_ADDR]], align 4
//
// Reload and adjust the this parameter:
- // CHECK: %[[THIS_RELOAD:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_ADDR]]
- // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS_RELOAD]] to i8*
- // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -24
- // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.diamond::D"*
+ // CHECK: %[[THIS_RELOAD:.*]] = load ptr, ptr %[[THIS_ADDR]]
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -24
//
- // CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8*
- // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i32 4
- // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"*
- // CHECK: %[[C_i8:.*]] = bitcast %"struct.diamond::C"* %[[C]] to i8*
- // CHECK: %[[ARG:.*]] = getelementptr i8, i8* %{{.*}}, i32 16
- // CHECK: call x86_thiscallcc void @"??1C at diamond@@UAE at XZ"(i8*{{[^,]*}} %[[ARG]])
-
- // CHECK: %[[B:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to %"struct.diamond::B"*
- // CHECK: %[[B_i8:.*]] = bitcast %"struct.diamond::B"* %[[B]] to i8*
- // CHECK: %[[ARG:.*]] = getelementptr i8, i8* %[[B_i8]], i32 4
- // CHECK: call x86_thiscallcc void @"??1B at diamond@@UAE at XZ"(i8*{{[^,]*}} %[[ARG]])
+ // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_ADJ_i8]], i32 4
+ // CHECK: %[[ARG:.*]] = getelementptr i8, ptr %{{.*}}, i32 16
+ // CHECK: call x86_thiscallcc void @"??1C at diamond@@UAE at XZ"(ptr{{[^,]*}} %[[ARG]])
+
+ // CHECK: %[[ARG:.*]] = getelementptr i8, ptr %[[THIS_ADJ_i8]], i32 4
+ // CHECK: call x86_thiscallcc void @"??1B at diamond@@UAE at XZ"(ptr{{[^,]*}} %[[ARG]])
// CHECK: ret void
}
@@ -332,20 +282,20 @@ struct C : B, A { C() {} };
// call to B() from C().
void callC() { C x; }
-// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef %"struct.test2::C"* @"??0C at test2@@QAE at XZ"
-// CHECK: (%"struct.test2::C"* {{[^,]*}} returned align 4 dereferenceable(8) %this, i32 noundef %is_most_derived)
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??0C at test2@@QAE at XZ"
+// CHECK: (ptr {{[^,]*}} returned align 4 dereferenceable(8) %this, i32 noundef %is_most_derived)
// CHECK: br i1
// Virtual bases
-// CHECK: call x86_thiscallcc noundef %"struct.test2::A"* @"??0A at test2@@QAE at XZ"(%"struct.test2::A"* {{[^,]*}} %{{.*}})
+// CHECK: call x86_thiscallcc noundef ptr @"??0A at test2@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
// CHECK: br label
// Non-virtual bases
-// CHECK: call x86_thiscallcc noundef %"struct.test2::B"* @"??0B at test2@@QAE at XZ"(%"struct.test2::B"* {{[^,]*}} %{{.*}}, i32 noundef 0)
-// CHECK: call x86_thiscallcc noundef %"struct.test2::A"* @"??0A at test2@@QAE at XZ"(%"struct.test2::A"* {{[^,]*}} %{{.*}})
+// CHECK: call x86_thiscallcc noundef ptr @"??0B at test2@@QAE at XZ"(ptr {{[^,]*}} %{{.*}}, i32 noundef 0)
+// CHECK: call x86_thiscallcc noundef ptr @"??0A at test2@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
// CHECK: ret
-// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef %"struct.test2::B"* @"??0B at test2@@QAE at XZ"
-// CHECK2: (%"struct.test2::B"* {{[^,]*}} returned align 4 dereferenceable(4) %this, i32 noundef %is_most_derived)
-// CHECK2: call x86_thiscallcc noundef %"struct.test2::A"* @"??0A at test2@@QAE at XZ"(%"struct.test2::A"* {{[^,]*}} %{{.*}})
+// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??0B at test2@@QAE at XZ"
+// CHECK2: (ptr {{[^,]*}} returned align 4 dereferenceable(4) %this, i32 noundef %is_most_derived)
+// CHECK2: call x86_thiscallcc noundef ptr @"??0A at test2@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
// CHECK2: ret
}
@@ -372,18 +322,14 @@ struct D : B, C {
};
void D::bar() {
- // CHECK-LABEL: define dso_local x86_thiscallcc void @"?bar at D@test3@@UAEXXZ"(%"struct.test3::D"* {{[^,]*}} %this)
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"?bar at D@test3@@UAEXXZ"(ptr {{[^,]*}} %this)
C::foo();
// Shouldn't need any vbtable lookups. All we have to do is adjust to C*,
// then compensate for the adjustment performed in the C::foo() prologue.
- // CHECK-NOT: load i8*, i8**
- // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test3::D"* %{{.*}} to i8*
- // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 8
- // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.test3::C"*
- // CHECK: %[[C_i8:.*]] = bitcast %"struct.test3::C"* %[[C]] to i8*
- // CHECK: %[[ARG:.*]] = getelementptr i8, i8* %[[C_i8]], i32 4
- // CHECK: call x86_thiscallcc void @"?foo at C@test3@@UAEXXZ"(i8* noundef %[[ARG]])
+ // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 8
+ // CHECK: %[[ARG:.*]] = getelementptr i8, ptr %[[C_i8]], i32 4
+ // CHECK: call x86_thiscallcc void @"?foo at C@test3@@UAEXXZ"(ptr noundef %[[ARG]])
// CHECK: ret
}
}
@@ -406,27 +352,25 @@ struct C : virtual A, B {
void foo(void*);
C::~C() {
- // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1C at test4@@UAE at XZ"(%"struct.test4::C"* {{[^,]*}} %this)
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1C at test4@@UAE at XZ"(ptr {{[^,]*}} %this)
// 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 i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7C at test4@@6BB at 1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+ // CHECK: store ptr @"??_7C at test4@@6BB at 1@@", ptr %{{.*}}
foo(this);
// CHECK: ret
}
void destroy(C *obj) {
- // CHECK-LABEL: define dso_local void @"?destroy at test4@@YAXPAUC at 1@@Z"(%"struct.test4::C"* noundef %obj)
+ // CHECK-LABEL: define dso_local void @"?destroy at test4@@YAXPAUC at 1@@Z"(ptr noundef %obj)
delete obj;
- // CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to i8* (%"struct.test4::C"*, i32)***
- // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::C"*, i32)**, i8* (%"struct.test4::C"*, i32)*** %[[VPTR]]
- // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0
- // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTENTRY]]
- // CHECK: call x86_thiscallcc noundef i8* %[[VFUN]](%"struct.test4::C"* {{[^,]*}} %[[OBJ]], i32 noundef 1)
+ // CHECK: %[[OBJ:.*]] = load ptr, ptr
+ // CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[OBJ]]
+ // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
+ // CHECK: %[[VFUN:.*]] = load ptr, ptr %[[VFTENTRY]]
+ // CHECK: call x86_thiscallcc noundef ptr %[[VFUN]](ptr {{[^,]*}} %[[OBJ]], i32 noundef 1)
// CHECK: ret
}
@@ -441,30 +385,24 @@ struct E : D, B, virtual A {
};
E::~E() {
- // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1E at test4@@UAE at XZ"(i8*{{[^,]*}} %this.coerce)
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1E at test4@@UAE at XZ"(ptr{{[^,]*}} %this)
// In this case "this" points to the most derived class, so no GEPs needed.
- // CHECK: bitcast i8* %this.coerce
// CHECK-NOT: getelementptr
- // CHECK-NOT: bitcast
- // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to i32 (...)***
- // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7E at test4@@6BD at 1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+ // CHECK: store ptr @"??_7E at test4@@6BD at 1@@", ptr %{{.*}}
foo(this);
}
void destroy(E *obj) {
- // CHECK-LABEL: define dso_local void @"?destroy at test4@@YAXPAUE at 1@@Z"(%"struct.test4::E"* noundef %obj)
+ // CHECK-LABEL: define dso_local void @"?destroy at test4@@YAXPAUE at 1@@Z"(ptr noundef %obj)
// CHECK-NOT: getelementptr
- // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ]] to i8*
- // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
- // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ:.*]] to i8*
- // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
- // CHECK: %[[VPTR:.*]] = bitcast i8* %[[B_i8]] to i8* (i8*, i32)***
- // CHECK: %[[VFTABLE:.*]] = load i8* (i8*, i32)**, i8* (i8*, i32)*** %[[VPTR]]
- // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (i8*, i32)*, i8* (i8*, i32)** %[[VFTABLE]], i64 0
- // CHECK: %[[VFUN:.*]] = load i8* (i8*, i32)*, i8* (i8*, i32)** %[[VFTENTRY]]
- // CHECK: call x86_thiscallcc noundef i8* %[[VFUN]](i8*{{[^,]*}} %[[THIS_i8]], i32 noundef 1)
+ // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, ptr %[[OBJ]], i32 4
+ // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, ptr %[[OBJ:.*]], i32 4
+ // CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[B_i8]]
+ // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 0
+ // CHECK: %[[VFUN:.*]] = load ptr, ptr %[[VFTENTRY]]
+ // CHECK: call x86_thiscallcc noundef ptr %[[VFUN]](ptr{{[^,]*}} %[[THIS_i8]], i32 noundef 1)
delete obj;
}
@@ -485,15 +423,13 @@ struct C : B {
};
C::C() : B() {}
-// CHECK-LABEL: define dso_local x86_thiscallcc noundef %"struct.test5::C"* @"??0C at test5@@QAE at XZ"(
-// CHECK: %[[THIS:.*]] = load %"struct.test5::C"*, %"struct.test5::C"**
+// CHECK-LABEL: define dso_local x86_thiscallcc noundef ptr @"??0C at test5@@QAE at XZ"(
+// CHECK: %[[THIS:.*]] = load ptr, ptr
// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
// CHECK: %[[SKIP_VBASES]]
-// CHECK: %[[B:.*]] = bitcast %"struct.test5::C"* %[[THIS]] to %"struct.test5::B"*
-// CHECK: %[[B_i8:.*]] = bitcast %"struct.test5::B"* %[[B]] to i8*
-// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[B_i8]], i32 4
-// CHECK: call void @llvm.memset.p0i8.i32(i8* align 4 %[[FIELD]], i8 0, i32 4, i1 false)
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 4
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 %[[FIELD]], i8 0, i32 4, i1 false)
}
namespace pr27621 {
@@ -509,9 +445,9 @@ struct C final : A, B {
void callit(C *p) {
static_cast<B*>(p)->g();
}
-// CHECK-LABEL: define dso_local void @"?callit at pr27621@@YAXPAUC at 1@@Z"(%"struct.pr27621::C"* noundef %{{.*}})
-// CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4
-// CHECK: call x86_thiscallcc void @"?g at C@pr27621@@UAEXXZ"(i8* noundef %[[B_i8]])
+// CHECK-LABEL: define dso_local void @"?callit at pr27621@@YAXPAUC at 1@@Z"(ptr noundef %{{.*}})
+// CHECK: %[[B_i8:.*]] = getelementptr i8, ptr %{{.*}}, i32 4
+// CHECK: call x86_thiscallcc void @"?g at C@pr27621@@UAEXXZ"(ptr noundef %[[B_i8]])
}
namespace test6 {
@@ -525,15 +461,13 @@ class D : C {
D();
};
D::D() : C() {}
-// CHECK-LABEL: define dso_local x86_thiscallcc noundef %"class.test6::D"* @"??0D at test6@@AAE at XZ"(
-// CHECK: %[[THIS:.*]] = load %"class.test6::D"*, %"class.test6::D"**
+// CHECK-LABEL: define dso_local x86_thiscallcc noundef ptr @"??0D at test6@@AAE at XZ"(
+// CHECK: %[[THIS:.*]] = load ptr, ptr
// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
// CHECK: %[[SKIP_VBASES]]
-// CHECK: %[[C:.*]] = bitcast %"class.test6::D"* %[[THIS]] to %"class.test6::C"*
-// CHECK: %[[C_i8:.*]] = bitcast %"class.test6::C"* %[[C]] to i8*
-// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[C_i8]], i32 8
-// CHECK: call void @llvm.memset.p0i8.i32(i8* align 4 %[[FIELD]], i8 0, i32 4, i1 false)
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, ptr %[[THIS]], i32 8
+// CHECK: call void @llvm.memset.p0.i32(ptr align 4 %[[FIELD]], i8 0, i32 4, i1 false)
}
namespace pr36921 {
@@ -546,12 +480,9 @@ struct B {
struct C : virtual B {};
struct D : virtual A, C {};
D d;
-// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef i8* @"??_GD at pr36921@@UAEPAXI at Z"(
-// CHECK2: %[[THIS:.*]] = load %"struct.pr36921::D"*, %"struct.pr36921::D"**
-// CHECK2: %[[THIS_RELOAD:.*]] = load %"struct.pr36921::D"*, %"struct.pr36921::D"**
-// CHECK2: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.pr36921::D"* %[[THIS_RELOAD]] to i8*
-// CHECK2: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -4
-// CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.pr36921::D"*
+// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_GD at pr36921@@UAEPAXI at Z"(
+// CHECK2: %[[THIS_RELOAD:.*]] = load ptr, ptr
+// CHECK2: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -4
}
namespace issue_60465 {
@@ -567,15 +498,14 @@ struct alignas(2 * sizeof(void *)) B : virtual A {
};
B::~B() {
-// The 'this' parameter should not have a type of %"struct.issue_60465::B"* and
+// The 'this' parameter should not have a type of ptr and
// must not have 'align 8', since at least B's copy of A is only 'align 4'.
-// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1B at issue_60465@@UAE at XZ"(i8* noundef %this.coerce)
-// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %{{.*}}, i32 -12
-// CHECK: %[[THIS_ADJ:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.issue_60465::B"*
-// CHECK: %[[X:.*]] = getelementptr inbounds %"struct.issue_60465::B", %"struct.issue_60465::B"* %[[THIS_ADJ]], i32 0, i32 1
-// CHECK: store i8* null, i8** %[[X]], align 4
-// CHECK: %[[Y:.*]] = getelementptr inbounds %"struct.issue_60465::B", %"struct.issue_60465::B"* %[[THIS_ADJ]], i32 0, i32 2
-// CHECK: store i8* null, i8** %[[Y]], align 8
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1B at issue_60465@@UAE at XZ"(ptr noundef %this)
+// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i32 -12
+// CHECK: %[[X:.*]] = getelementptr inbounds %"struct.issue_60465::B", ptr %[[THIS_ADJ_i8]], i32 0, i32 1
+// CHECK: store ptr null, ptr %[[X]], align 4
+// CHECK: %[[Y:.*]] = getelementptr inbounds %"struct.issue_60465::B", ptr %[[THIS_ADJ_i8]], i32 0, i32 2
+// CHECK: store ptr null, ptr %[[Y]], align 8
x = nullptr;
y = nullptr;
}
More information about the cfe-commits
mailing list