562 lines · cpp
1// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -triple x86_64-unknown-linux-gnu -o - | FileCheck %s2 3template <typename T>4struct IsChar {5 constexpr operator bool() const { return false; }6};7 8template<>9struct IsChar<char> {10 constexpr operator bool() const { return true; }11};12 13template <typename T>14concept SameAsChar = (bool)IsInt<T>();15 16// CHECK-DAG: [[STRUCT_A:%.*]] = type { i8, double }17struct A {18 char i;19 double j;20 21 template <SameAsChar T>22 operator T() const { return i; };23};24 25// CHECK-DAG: [[STRUCT_B:%.*]] = type { [[STRUCT_A]], i32 }26struct B {27 A a;28 int b;29};30 31// CHECK-DAG: [[STRUCT_C:%.*]] = type <{ [[STRUCT_B]], [[STRUCT_A]], i32, [4 x i8] }>32struct C : public B, public A {33 int c;34};35 36// CHECK-DAG: [[STRUCT_D:%.*]] = type { [[STRUCT_A]], [[STRUCT_A]], i8, [[STRUCT_A]] }37struct D {38 A a;39 A b = A{2, 2.0};40 unsigned : 2;41 A c;42};43 44// CHECK-DAG: [[STRUCT_E:%.*]] = type { i32, ptr }45struct E {46 int a;47 const char* fn = __builtin_FUNCTION();48 ~E() {};49};50 51struct F {52 F (int i = 1);53 F (const F &f) = delete;54 F (F &&f) = default;55};56 57// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [4 x i8] }>58struct G {59 int a;60 F f;61};62 63// CHECK-DAG: [[UNION_U:%.*]] = type { [[STRUCT_A]] }64// CHECK-DAG: [[STR:@.*]] = private unnamed_addr constant [6 x i8] {{.*}}foo18{{.*}}, align 165union U {66 unsigned : 1;67 A a;68 char b;69};70 71 72namespace gh61145 {73 // CHECK-DAG: [[STRUCT_VEC:%.*]] = type { i8 }74 struct Vec {75 Vec();76 Vec(Vec&&);77 ~Vec();78 };79 80 // CHECK-DAG: [[STRUCT_S1:%.*]] = type { i8 }81 struct S1 {82 Vec v;83 };84 85 // CHECK-DAG: [[STRUCT_S2:%.*]] = type { i8, i8 }86 struct S2 {87 Vec v;88 char c;89 };90}91 92namespace gh62266 {93 // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, i32 }94 template <int J>95 struct H {96 int i;97 int j = J;98 };99}100 101namespace gh61567 {102 // CHECK-DAG: [[STRUCT_I:%.*I.*]] = type { i32, ptr }103 struct I {104 int a;105 int&& r = 2;106 };107}108 109// CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8110constexpr A a1(3.1, 2.0);111// CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8112constexpr auto a2 = static_cast<A>('c');113// CHECK-DAG: [[B1:@.*b1.*]] = internal constant [[STRUCT_B]] { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0 }, align 8114constexpr B b1(A('c'));115// CHECK-DAG: [[C1:@.*c1.*]] = internal constant { [[STRUCT_A]], i32, [4 x i8], i8, double, i32 } { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0, [4 x i8] undef, i8 3, double 2.000000e+00, i32 0 }, align116constexpr C c1(b1, a1);117// CHECK-DAG: [[U1:@.*u1.*]] = internal constant [[UNION_U]] { [[STRUCT_A]] { i8 1, double 1.000000e+00 } }, align 8118constexpr U u1(A(1, 1));119// CHECK-DAG: [[D1:@.*d1.*]] = internal constant { [[STRUCT_A]], [[STRUCT_A]], [8 x i8], [[STRUCT_A]] } { [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [8 x i8] undef, [[STRUCT_A]] zeroinitializer }, align 8120constexpr D d1(A(2, 2));121// CHECK-DAG: [[ARR1:@.*arr1.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 0], align 4122constexpr int arr1[3](1, 2);123// CHECK-DAG: [[ARR4:@.*arr4.*]] = internal constant [1 x i32] [i32 1], align 4124constexpr int arr4[](1);125// CHECK-DAG: [[ARR5:@.*arr5.*]] = internal constant [2 x i32] [i32 2, i32 0], align 4126constexpr int arr5[2](2);127 128// CHECK: define dso_local { i8, double } @{{.*foo1.*}}129// CHECK-NEXT: entry:130// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_A]], align 8131// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A1]], i64 16, i1 false)132// CHECK-NEXT: [[TMP_0:%.*]] = load { i8, double }, ptr [[RETVAL]], align 8133// CHECK-NEXT: ret { i8, double } [[TMP_0]]134A foo1() {135 return a1;136}137 138// CHECK: define dso_local void @{{.*foo2.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_B]]) align 8 [[AGG_RESULT:%.*]])139// CHECK-NEXT: entry:140// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[B1]], i64 24, i1 false)141// CHECK-NEXT: ret void142B foo2() {143 return b1;144}145 146// CHECK: define dso_local void @{{.*foo3.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_C]]) align 8 [[AGG_RESULT:%.*]])147// CHECK-NEXT: entry:148// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[C1]], i64 48, i1 false)149// CHECK-NEXT: ret void150C foo3() {151 return c1;152}153 154// CHECK: define dso_local void @{{.*foo4.*}}155// CHECK-NEXT: entry:156// CHECK-NEXT: [[C2:%.*]] = alloca [[STRUCT_C:%.*]], align 8157// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_B:%.*]], align 8158// CHECK-NEXT: [[REF_TMP_1:%.*]] = alloca [[STRUCT_A:%.*]], align 8159// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 0160// CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 0161// CHECK-NEXT: store i8 1, ptr [[I]], align 8162// CHECK-NEXT: [[J:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 1163// CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8164// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 1165// CHECK-NEXT: store i32 1, ptr [[B]], align 8166// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[C2]], ptr align 8 [[REF_TMP]], i64 24, i1 false)167// CHECK-NEXT: [[TMP_0:%.*]] = getelementptr inbounds i8, ptr [[C2]], i64 24168// CHECK-NEXT: [[I2:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 0169// CHECK-NEXT: store i8 97, ptr [[I2]], align 8170// CHECK-NEXT: [[J3:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 1171// CHECK-NEXT: store double 0.000000e+00, ptr [[J3]], align 8172// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP_0]], ptr align 8 [[REF_TMP_1]], i64 16, i1 false)173// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw %struct.C, ptr %c2, i32 0, i32 2174// CHECK-NEXT: store i32 2, ptr %c, align 8175// CHECK-NEXT: ret void176void foo4() {177 C c2(B(A(1, 1), 1), A('a'), 2);178}179 180// CHECK: define dso_local { i64, double } @{{.*foo5.*}}181// CHECK-NEXT: entry:182// CHECK-NEXT [[RETVAL:%.*]] = alloca [[UNION_U]], align 8183// CHECK-NEXT call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[U1]], i64 16, i1 false)184// CHECK-NEXT [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_U]], ptr %retval, i32 0, i32 0185// CHECK-NEXT [[TMP_0:%.*]] = load { i64, double }, ptr [[COERCE_DIVE]], align 8186// CHECK-NEXT ret { i64, double } [[TMP_0]]187U foo5() {188 return u1;189}190 191 192// CHECK: define dso_local { i64, double } @{{.*foo6.*}}(i8 [[A_COERCE_0:%.*]], double [[A_COERCE_1:%.*]])193// CHECK-NEXT: entry:194// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[UNION_U]], align 8195// CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A]], align 8196// CHECK-NEXT: [[TMP_0:%.*]] = getelementptr inbounds nuw { i8, double }, ptr [[A]], i32 0, i32 0197// CHECK-NEXT: store i8 [[A_COERCE_0]], ptr [[TMP_0]], align 8198// CHECK-NEXT: [[TMP_1:%.*]] = getelementptr inbounds nuw { i8, double }, ptr [[A]], i32 0, i32 1199// CHECK-NEXT: store double [[A_COERCE_1]], ptr [[TMP_1]], align 8200// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A]], i64 16, i1 false)201// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_U]], ptr [[RETVAL]], i32 0, i32 0202// CHECK-NEXT: [[TMP_2:%.*]] = load { i64, double }, ptr [[COERCE_DIVE:%.*]], align 8203// CHECK-NEXT: ret { i64, double } [[TMP_2]]204U foo6(A a) {205 return U(a);206}207 208// CHECK: define dso_local void @{{.*foo7.*}}209// CHECK-NEXT: entry:210// CHECK-NEXT: [[D:%.*]] = alloca [[STRUCT_D:%.*]], align 8211// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 0212// CHECK-NEXT: [[I]] = getelementptr inbounds nuw [[STRUCT_A:%.*]], ptr [[A]], i32 0, i32 0213// CHECK-NEXT: store i8 1, ptr [[I]], align 8214// CHECK-NEXT: [[J:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 1215// CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8216// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 1217// CHECK-NEXT: [[I1:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 0218// CHECK-NEXT: store i8 11, ptr [[I1]], align 8219// CHECK-NEXT: [[J2:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 1220// CHECK-NEXT: store double 1.100000e+01, ptr [[J2]], align 8221// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 3222// CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[C]], i32 0, i32 0223// CHECK-NEXT: store i8 111, ptr [[I3]], align 8224// CHECK-NEXT: [[J4:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[C]], i32 0, i32 1225// CHECK-NEXT: store double 1.110000e+02, ptr [[J4]], align 8226// CHECK-NEXT: ret void227void foo7() {228 D d(A(1, 1), A(11, 11), A(111, 111));229}230 231// CHECK: dso_local void @{{.*foo8.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_D]]) align 8 [[AGG_RESULT:%.*]])232// CHECK-NEXT: entry:233// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[D1]], i64 56, i1 false)234// CHECK-NEXT: ret void235D foo8() {236 return d1;237}238 239// CHECK: define dso_local void @{{.*foo9.*}}240// CHECK-NEXT: entry:241// CHECK-NEXT: [[D:%.*]] = alloca [[STRUCT_D:%.*]], align 8242// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 0243// CHECK-NEXT: [[I]] = getelementptr inbounds nuw [[STRUCT_A:%.*]], ptr [[A]], i32 0, i32 0244// CHECK-NEXT: store i8 1, ptr [[I]], align 8245// CHECK-NEXT: [[J:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 1246// CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8247// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 1248// CHECK-NEXT: [[I1:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 0249// CHECK-NEXT: store i8 2, ptr [[I1]], align 8250// CHECK-NEXT: [[J2:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 1251// CHECK-NEXT: store double 2.000000e+00, ptr [[J2]], align 8252// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 3253// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[C]], i8 0, i64 16, i1 false)254// CHECK-NEXT: ret void255void foo9() {256 D d(A(1, 1));257}258 259// CHECK: define dso_local noundef ptr @{{.*foo10.*}}()260// CHECK-NEXT: entry:261// CHECK-NEXT: ret ptr [[ARR1]]262const int* foo10() {263 return arr1;264}265 266// CHECK: define dso_local void @{{.*foo11.*}}267// CHECK-NEXT: entry:268// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4269// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4270// CHECK-NEXT: [[ARR_2:%.*]] = alloca [4 x i32], align 16271// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4272// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4273// CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4274// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARR_2]], align 4275// CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 1276// CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4277// CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEM]], align 4278// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 2279// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 4280// CHECK-NEXT: br label [[ARRINIT_BODY:%.*]]281// CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ]282// CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4283// CHECK-NEXT: [[ARRINIT_NEXT]] = getelementptr inbounds i32, ptr [[ARRINIT_CUR]], i64 1284// CHECK-NEXT: [[ARRINIT_DONE:%.*]] = icmp eq ptr [[ARRINIT_NEXT]], [[ARRINIT_END:%.*]]285// CHECK-NEXT: br i1 [[ARRINIT_DONE]], label [[ARRINIT_END1:%.*]], label [[ARRINIT_BODY]]286// CHECK: ret void287void foo11(int a, int b) {288 int arr2[4](a, b);289}290 291// CHECK: define dso_local void @{{.*foo12.*}}292// CHECK-NEXT: entry:293// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4294// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4295// CHECK-NEXT: [[ARR_3:%.*]] = alloca [2 x i32], align 4296// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4297// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4298// CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4299// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARR_3]], align 4300// CHECK-NEXT: [[ARRINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[ARR_3]], i64 1301// CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4302// CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEMENT]], align 4303// CHECK-NEXT: ret void304void foo12(int a, int b) {305 int arr3[](a, b);306}307 308// CHECK: define dso_local { i8, double } @{{.*foo13.*}}309// CHECK-NEXT: entry:310// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_A]], align 8311// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A2]], i64 16, i1 false)312// CHECK-NEXT: [[TMP_0:%.*]] = load { i8, double }, ptr [[RETVAL]], align 8313// CHECK-NEXT: ret { i8, double } [[TMP_0]]314A foo13() {315 return a2;316}317 318// CHECK: define dso_local noundef ptr @{{.*foo14.*}}()319// CHECK-NEXT: entry:320// CHECK-NEXT: ret ptr [[ARR4]]321const int* foo14() {322 return arr4;323}324 325// CHECK: define dso_local noundef ptr @{{.*foo15.*}}()326// CHECK-NEXT: entry:327// CHECK-NEXT: ret ptr [[ARR5]]328const int* foo15() {329 return arr5;330}331 332// CHECK: define dso_local void @{{.*foo16.*}}333// CHECK-NEXT: entry:334// CHECK-NEXT: [[ARR_6:%.*arr6.*]] = alloca ptr, align 8335// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [1 x i32], align 4336// CHECK-NEXT: store i32 3, ptr [[REF_TMP]], align 4337// CHECK-NEXT: store ptr [[REF_TMP]], ptr [[ARR_6]], align 8338// CHECK-NEXT: ret void339void foo16() {340 int (&&arr6)[] = static_cast<int[]>(3);341}342 343// CHECK: define dso_local void @{{.*foo17.*}}344// CHECK-NEXT: entry:345// CHECK-NEXT: [[ARR_7:%.*arr7.*]] = alloca ptr, align 8346// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [2 x i32], align 4347// CHECK-NEXT: store i32 4, ptr [[REF_TMP]], align 4348// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[REF_TMP]], i64 1349// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[REF_TMP]], i64 2350// CHECK-NEXT: br label [[ARRINIT_BODY]]351// CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ]352// CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4353// CHECK-NEXT: [[ARRINIT_NEXT]] = getelementptr inbounds i32, ptr [[ARRINIT_CUR]], i64 1354// CHECK-NEXT: [[ARRINIT_DONE:%.*]] = icmp eq ptr [[ARRINIT_NEXT]], [[ARRINIT_END:%.*]]355// CHECK-NEXT: br i1 [[ARRINIT_DONE]], label [[ARRINIT_END1:%.*]], label [[ARRINIT_BODY]]356// CHECK: store ptr [[REF_TMP]], ptr [[ARR_7]], align 8357// CHECK: ret void358void foo17() {359 int (&&arr7)[2] = static_cast<int[2]>(4);360}361 362// CHECK: define dso_local void @{{.*foo18.*}}363// CHECK-NEXT: entry:364// CHECK-NEXT: [[E:%.*e.*]] = alloca [[STRUCT_E]], align 8365// CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_E]], ptr [[E]], i32 0, i32 0366// CHECK-NEXT: store i32 1, ptr [[A]], align 8367// CHECK-NEXT: [[FN:%.*fn.*]] = getelementptr inbounds nuw [[STRUCT_E]], ptr [[E]], i32 0, i32 1368// CHECK-NEXT: store ptr [[STR]], ptr [[FN]], align 8369// CHECK: ret void370void foo18() {371 E e(1);372}373 374// CHECK: define dso_local void @{{.*foo19.*}}375// CHECK-NEXT: entry:376// CHECK-NEXT: [[G:%.*g.*]] = alloca [[STRUCT_G]], align 4377// CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_G]], ptr [[G]], i32 0, i32 0378// CHECK-NEXT: store i32 2, ptr [[A]], align 4379// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds i8, ptr [[G]], i64 4380// CHECK-NEXT: call void @{{.*F.*}}(ptr noundef nonnull align 1 dereferenceable(1) [[F]], i32 noundef 1)381// CHECK: ret void382void foo19() {383 G g(2);384}385 386namespace gh61145 {387 // a.k.a. void make1<0>()388 // CHECK: define {{.*}} void @_ZN7gh611455make1ILi0EEEvv389 // CHECK-NEXT: entry:390 // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1391 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S1]], align 1392 // a.k.a. Vec::Vec()393 // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])394 // a.k.a. Vec::Vec(Vec&&)395 // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])396 // a.k.a. S1::~S1()397 // CHECK-NEXT: call void @_ZN7gh611452S1D1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]])398 // a.k.a.Vec::~Vec()399 // CHECK-NEXT: call void @_ZN7gh611453VecD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])400 // CHECK-NEXT: ret void401 template <int I>402 void make1() {403 Vec v;404 S1((Vec&&) v);405 }406 407 // a.k.a. void make1<0>()408 // CHECK: define {{.*}} void @_ZN7gh611455make2ILi0EEEvv409 // CHECK-NEXT: entry:410 // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1411 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S2]], align 1412 // a.k.a. Vec::Vec()413 // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])414 // a.k.a. Vec::Vec(Vec&&)415 // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])416 // CHECK-NEXT: [[C:%.*c.*]] = getelementptr inbounds nuw [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32417 // CHECK-NEXT: store i8 0, ptr [[C]], align 1418 // a.k.a. S2::~S2()419 // CHECK-NEXT: call void @_ZN7gh611452S2D1Ev(ptr noundef nonnull align 1 dereferenceable(2) [[AGG_TMP_ENSURED]])420 // a.k.a. Vec::~Vec()421 // CHECK-NEXT: call void @_ZN7gh611453VecD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])422 // CHECK-NEXT: ret void423 template <int I>424 void make2() {425 Vec v;426 S2((Vec&&) v, 0);427 }428 429 void foo() {430 make1<0>();431 make2<0>();432 }433}434 435namespace gh62266 {436 // CHECK: define {{.*}} void {{.*foo20.*}}437 // CHECK-NEXT: entry:438 // CHECK-NEXT: [[H:%.*h.*]] = alloca [[STRUCT_H]], align 4439 // CHECK-NEXT: [[I:%.*i.*]] = getelementptr inbounds nuw [[STRUCT_H]], ptr [[H]], i32 0, i32 0440 // CHECK-NEXT: store i32 1, ptr [[I]], align 4441 // CHECK-NEXT: [[J:%.*j.*]] = getelementptr inbounds nuw [[STRUCT_H]], ptr [[H]], i32 0, i32 1442 // CHECK-NEXT: store i32 2, ptr [[J]], align 4443 // CHECK-NEXT: ret void444 void foo20() {445 H<2> h(1);446 }447}448 449namespace gh61567 {450 int foo20();451 452 // CHECK: define {{.*}} void @{{.*foo21.*}} {453 // CHECK-NEXT: entry454 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8455 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4456 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0457 // CHECK-NEXT: store i32 0, ptr [[A]], align 8458 // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1459 // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4460 // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8461 // CHECK-NEXT: ret void462 void foo21() {463 I(0, 1);464 }465 466 // CHECK: define {{.*}} void @{{.*foo22.*}} {467 // CHECK-NEXT: entry468 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8469 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4470 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0471 // CHECK-NEXT: store i32 0, ptr [[A]], align 8472 // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1473 // CHECK-NEXT: [[CALL:%.*call*]] = call noundef i32 @{{.*foo20.*}}474 // CHECK-NEXT: store i32 [[CALL]], ptr [[REF_TMP]], align 4475 // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8476 // CHECK-NEXT: ret void477 void foo22() {478 I(0, foo20());479 }480 481 // CHECK: define {{.*}} void @{{.*foo23.*}}(i32 noundef [[I:%.*i.*]])482 // CHECK-NEXT: entry483 // CHECK-NEXT: [[I_ADDR:%.*i.*]] = alloca i32, align 4484 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8485 // CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4486 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0487 // CHECK-NEXT: store i32 0, ptr [[A]], align 8488 // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1489 // CHECK-NEXT: store ptr [[I_ADDR]], ptr [[R]], align 8490 // CHECK-NEXT: ret void491 void foo23(int i) {492 I(0, static_cast<int&&>(i));493 }494 495 // CHECK: define {{.*}} void @{{.*foo24.*}} {496 // CHECK-NEXT: entry497 // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8498 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4499 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0500 // CHECK-NEXT: store i32 0, ptr [[A]], align 8501 // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1502 // CHECK-NEXT: store i32 2, ptr [[REF_TMP]], align 4503 // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8504 // CHECK-NEXT: ret void505 void foo24() {506 I(0);507 }508}509 510namespace gh68198 {511 // CHECK: define {{.*}} void @{{.*foo25.*}} {512 // CHECK-NEXT: entry513 // CHECK-NEXT: [[ARR_8:%.*arr8.*]] = alloca ptr, align 8514 // CHECK-NEXT: [[CALL_PTR:%.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 8)515 // CHECK-NEXT: store i32 1, ptr [[CALL_PTR]], align 4516 // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds i32, ptr [[CALL_PTR]], i64 1517 // CHECK-NEXT: store i32 2, ptr [[ARRAY_EXP_NEXT]], align 4518 // CHECK-NEXT: [[ARRAY_EXP_NEXT1:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1519 // CHECK-NEXT: store ptr [[CALL_PTR]], ptr %arr8, align 8520 // CHECK-NEXT: ret void521 void foo25() {522 int* arr8 = new int[](1, 2);523 }524 525 // CHECK: define {{.*}} void @{{.*foo26.*}} {526 // CHECK-NEXT: entry527 // CHECK-NEXT: [[ARR_10:%.*arr9.*]] = alloca ptr, align 8528 // CHECK-NEXT: [[CALL_PTR]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 16)529 // CHECK-NEXT: store i32 1, ptr [[CALL]], align 4530 // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 1531 // CHECK-NEXT: store i32 2, ptr [[ARRAYINIT_ELEMENT]], align 4532 // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds [2 x i32], ptr %call, i64 1533 // CHECK-NEXT: store i32 3, ptr [[ARRAY_EXP_NEXT]], align 4534 // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1535 // CHECK-NEXT: store i32 4, ptr [[ARRAYINIT_ELEMENT2]], align 4536 // CHECK-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1537 // CHECK-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_10]], align 8538 // CHECK-NEXT: ret void539 void foo26() {540 void* arr9 = new int[][2]({1, 2}, {3, 4});541 }542 543 // CHECK: define {{.*}} void @{{.*foo27.*}} {544 // CHECK-NEXT: entry545 // CHECK-NEXT: [[ARR_10:%.*arr10.*]] = alloca ptr, align 8546 // CHECK-NEXT: [[CALL_PTR]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 32)547 // CHECK-NEXT: store i32 5, ptr [[CALL]], align 4548 // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 1549 // CHECK-NEXT: store i32 6, ptr [[ARRAYINIT_ELEMENT]], align 4550 // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds [2 x i32], ptr %call, i64 1551 // CHECK-NEXT: store i32 7, ptr [[ARRAY_EXP_NEXT]], align 4552 // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1553 // CHECK-NEXT: store i32 8, ptr [[ARRAYINIT_ELEMENT2]], align 4554 // CHECK-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1555 // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAY_EXP_NEXT3]], i8 0, i64 16, i1 false)556 // CHECK-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_10]], align 8557 // CHECK-NEXT: ret void558 void foo27() {559 void* arr10 = new int[4][2]({5, 6}, {7, 8});560 }561}562