[InstCombine] Preserve NSW flags for `lshr (mul nuw X, C1), C2 -> mul nuw nsw X,...
[llvm-project.git] / clang / test / CodeGenCXX / cxx2a-destroying-delete.cpp
blob20264b67353a979cd024ab0e0fda342400fb888f
1 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ITANIUM,CHECK-64BIT
2 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT
3 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple i386-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI32,CHECK-32BIT
5 // PR46908: ensure the IR passes the verifier with optimizations enabled.
6 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple x86_64-linux-gnu -O2
7 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple x86_64-windows -O2
8 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple i386-windows -O2
10 namespace std {
11 using size_t = decltype(sizeof(0));
12 enum class align_val_t : size_t;
13 struct destroying_delete_t {};
16 struct A {
17 void *data;
18 ~A();
19 void operator delete(A*, std::destroying_delete_t);
21 void delete_A(A *a) { delete a; }
22 // CHECK-LABEL: define {{.*}}delete_A
23 // CHECK: %[[a:.*]] = load
24 // CHECK: icmp eq ptr %[[a]], null
25 // CHECK: br i1
27 // Ensure that we call the destroying delete and not the destructor.
28 // CHECK-NOT: call
29 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(ptr noundef %[[a]])
30 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], i8
31 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}})
32 // CHECK-NOT: call
33 // CHECK: }
35 struct B {
36 virtual ~B();
37 void operator delete(B*, std::destroying_delete_t);
39 void delete_B(B *b) { delete b; }
40 // CHECK-LABEL: define {{.*}}delete_B
41 // CHECK: %[[b:.*]] = load
42 // CHECK: icmp eq ptr %[[b]], null
43 // CHECK: br i1
45 // Ensure that we call the virtual destructor and not the operator delete.
46 // CHECK-NOT: call
47 // CHECK: %[[VTABLE:.*]] = load
48 // CHECK: %[[DTOR:.*]] = load
49 // CHECK: call {{void|noundef ptr|x86_thiscallcc noundef ptr}} %[[DTOR]](ptr {{[^,]*}} %[[b]]
50 // CHECK-MSABI-SAME: , i32 noundef 1)
51 // CHECK-NOT: call
52 // CHECK: }
54 struct Padding {
55 virtual void f();
58 struct C : Padding, A {};
59 void delete_C(C *c) { delete c; }
60 // Check that we perform a derived-to-base conversion on the parameter to 'operator delete'.
61 // CHECK-LABEL: define {{.*}}delete_C
62 // CHECK: %[[c:.*]] = load
63 // CHECK: icmp eq ptr %[[c]], null
64 // CHECK: br i1
66 // CHECK-64BIT: %[[base:.*]] = getelementptr {{.*}}, i64 8
67 // CHECK-32BIT: %[[base:.*]] = getelementptr {{.*}}, i32 4
69 // CHECK: %[[a:.*]] = phi {{.*}} %[[base]]
70 // CHECK: icmp eq ptr %[[a]], null
71 // CHECK: br i1
73 // CHECK-NOT: call
74 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(ptr noundef %[[a]])
75 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], i8
76 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}})
77 // CHECK-NOT: call
78 // CHECK: }
80 struct VDel { virtual ~VDel(); };
81 struct D : Padding, VDel, B {};
82 void delete_D(D *d) { delete d; }
83 // CHECK-LABEL: define {{.*}}delete_D
84 // CHECK: %[[d:.*]] = load
85 // CHECK: icmp eq ptr %[[d]], null
86 // CHECK: br i1
88 // CHECK-NOT: call
89 // For MS, we don't add a new vtable slot to the primary vtable for the virtual
90 // destructor. Instead we cast to the VDel base class.
91 // CHECK-MSABI64: %[[d:.*]] = getelementptr {{.*}}, i64 8
92 // CHECK-MSABI32: %[[d:.*]] = getelementptr {{.*}}, i32 4
94 // CHECK: %[[VTABLE:.*]] = load
95 // CHECK: %[[DTOR:.*]] = load
97 // CHECK: call {{void|noundef ptr|x86_thiscallcc noundef ptr}} %[[DTOR]](ptr{{[^,]*}} %[[d]]
98 // CHECK-MSABI-SAME: , i32 noundef 1)
99 // CHECK-NOT: call
100 // CHECK: }
102 struct J {
103 J(); // might throw
104 void operator delete(J *, std::destroying_delete_t);
107 // CHECK-ITANIUM-LABEL: define {{.*}}@_Z1j
108 // CHECK-MSABI-LABEL: define {{.*}}@"?j@@
109 J *j() {
110 // CHECK-ITANIUM: invoke {{.*}}@_ZN1JC1Ev(
111 // CHECK-ITANIUM: call {{.*}}@_ZdlPv(
112 // CHECK-NOT: }
113 // CHECK-MSABI: invoke {{.*}}@"??0J@@Q{{AE|EAA}}@XZ"(
114 // CHECK-MSABI: call {{.*}}@"??3@YAXP{{E?}}AX@Z"(
115 return new J;
116 // CHECK: }
119 struct K {
120 K(); // might throw
121 void operator delete(void *);
122 void operator delete(K *, std::destroying_delete_t);
125 // CHECK-ITANIUM-LABEL: define {{.*}}@_Z1k
126 // CHECK-MSABI-LABEL: define {{.*}}@"?k@@
127 K *k() {
128 // CHECK-ITANIUM: invoke {{.*}}@_ZN1KC1Ev(
129 // CHECK-ITANIUM: call {{.*}}@_ZN1KdlEPv(
130 // CHECK-NOT: }
131 // CHECK-MSABI: invoke {{.*}}@"??0K@@Q{{AE|EAA}}@XZ"(
132 // CHECK-MSABI: call {{.*}}@"??3K@@SAXP{{E?}}AX@Z"(
133 return new K;
134 // CHECK: }
137 struct E { void *data; };
138 struct F { void operator delete(F *, std::destroying_delete_t, std::size_t, std::align_val_t); void *data; };
139 struct alignas(16) G : E, F { void *data; };
141 void delete_G(G *g) { delete g; }
142 // CHECK-LABEL: define {{.*}}delete_G
143 // CHECK-NOT: call
144 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(ptr noundef %[[a]], i64 noundef 32, i64 noundef 16)
145 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(ptr noundef %[[a]], i8 {{[^,]*}}, i64 noundef 32, i64 noundef 16)
146 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}}, i32 noundef 16, i32 noundef 16)
147 // CHECK-NOT: call
148 // CHECK: }
150 void call_in_dtor();
152 struct H : G { virtual ~H(); } h;
153 H::~H() { call_in_dtor(); }
154 // CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1HD0Ev(
155 // CHECK-ITANIUM-NOT: call
156 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24
157 // CHECK-ITANIUM-NOT: call
158 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 48, i64 noundef 16)
159 // CHECK-ITANIUM-NOT: call
160 // CHECK-ITANIUM: }
162 // CHECK-MSABI64-LABEL: define {{.*}} @"??_GH@@UEAAPEAXI@Z"(
163 // CHECK-MSABI32-LABEL: define {{.*}} @"??_GH@@UAEPAXI@Z"(
164 // CHECK-MSABI-NOT: call{{ }}
165 // CHECK-MSABI: load i32
166 // CHECK-MSABI: icmp eq i32 {{.*}}, 0
167 // CHECK-MSABI: br i1
169 // CHECK-MSABI-NOT: call{{ }}
170 // CHECK-MSABI64: getelementptr {{.*}}, i64 24
171 // CHECK-MSABI32: getelementptr {{.*}}, i32 20
172 // CHECK-MSABI-NOT: call{{ }}
173 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 48, i64 noundef 16)
174 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 32, i32 noundef 16)
175 // CHECK-MSABI: br label %[[RETURN:.*]]
177 // CHECK-MSABI64: call void @"??1H@@UEAA@XZ"(
178 // CHECK-MSABI32: call x86_thiscallcc void @"??1H@@UAE@XZ"(
179 // CHECK-MSABI: br label %[[RETURN]]
181 // CHECK-MSABI: }
183 struct I : H { virtual ~I(); alignas(32) char buffer[32]; } i;
184 I::~I() { call_in_dtor(); }
185 // CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1ID0Ev(
186 // CHECK-ITANIUM-NOT: call
187 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24
188 // CHECK-ITANIUM-NOT: call
189 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 96, i64 noundef 32)
190 // CHECK-ITANIUM-NOT: call
191 // CHECK-ITANIUM: }
193 // CHECK-MSABI64-LABEL: define {{.*}} @"??_GI@@UEAAPEAXI@Z"(
194 // CHECK-MSABI32-LABEL: define {{.*}} @"??_GI@@UAEPAXI@Z"(
195 // CHECK-MSABI-NOT: call{{ }}
196 // CHECK-MSABI: load i32
197 // CHECK-MSABI: icmp eq i32 {{.*}}, 0
198 // CHECK-MSABI: br i1
200 // CHECK-MSABI-NOT: call{{ }}
201 // CHECK-MSABI64: getelementptr {{.*}}, i64 24
202 // CHECK-MSABI32: getelementptr {{.*}}, i32 20
203 // CHECK-MSABI-NOT: call{{ }}
204 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 96, i64 noundef 32)
205 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 64, i32 noundef 32)
206 // CHECK-MSABI: br label %[[RETURN:.*]]
208 // CHECK-MSABI64: call void @"??1I@@UEAA@XZ"(
209 // CHECK-MSABI32: call x86_thiscallcc void @"??1I@@UAE@XZ"(
210 // CHECK-MSABI: br label %[[RETURN]]
212 // CHECK-MSABI: }