xref: /aosp_15_r20/external/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li // PR10878
4*67e74705SXin Li 
5*67e74705SXin Li struct S { S(); S(int); ~S(); int n; };
6*67e74705SXin Li 
7*67e74705SXin Li void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
8*67e74705SXin Li 
9*67e74705SXin Li // CHECK-LABEL: define
10*67e74705SXin Li // CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 32)
11*67e74705SXin Li // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
12*67e74705SXin Li // CHECK: store i64 6, i64* %[[COOKIE]]
13*67e74705SXin Li // CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8
14*67e74705SXin Li // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S:.*]]*
15*67e74705SXin Li //
16*67e74705SXin Li // Explicit initializers:
17*67e74705SXin Li //
18*67e74705SXin Li // { 1, 2, 3 }
19*67e74705SXin Li //
20*67e74705SXin Li // CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
21*67e74705SXin Li //
22*67e74705SXin Li // CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
23*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
24*67e74705SXin Li // CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_0]], i64 1
25*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
26*67e74705SXin Li // CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_1]], i64 1
27*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
28*67e74705SXin Li //
29*67e74705SXin Li // { 4, 5, 6 }
30*67e74705SXin Li //
31*67e74705SXin Li // CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 1
32*67e74705SXin Li //
33*67e74705SXin Li // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
34*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
35*67e74705SXin Li // CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_0]], i64 1
36*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
37*67e74705SXin Li // CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_1]], i64 1
38*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
39*67e74705SXin Li //
40*67e74705SXin Li // CHECK-NOT: br i1
41*67e74705SXin Li // CHECK-NOT: call
42*67e74705SXin Li // CHECK: }
43*67e74705SXin Li 
44*67e74705SXin Li int n;
45*67e74705SXin Li void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
46*67e74705SXin Li 
47*67e74705SXin Li // CHECK-LABEL: define
48*67e74705SXin Li //
49*67e74705SXin Li // CHECK: load i32, i32* @n
50*67e74705SXin Li // CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
51*67e74705SXin Li // CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
52*67e74705SXin Li // CHECK: call {{.*}} @llvm.uadd.with.overflow.i64(i64 %{{.*}}, i64 8)
53*67e74705SXin Li // CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}})
54*67e74705SXin Li //
55*67e74705SXin Li // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
56*67e74705SXin Li // CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]]
57*67e74705SXin Li // CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8
58*67e74705SXin Li // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S]]*
59*67e74705SXin Li //
60*67e74705SXin Li // Explicit initializers:
61*67e74705SXin Li //
62*67e74705SXin Li // { 1, 2, 3 }
63*67e74705SXin Li //
64*67e74705SXin Li // CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
65*67e74705SXin Li //
66*67e74705SXin Li // CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
67*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
68*67e74705SXin Li // CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_0]], i64 1
69*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
70*67e74705SXin Li // CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_1]], i64 1
71*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
72*67e74705SXin Li //
73*67e74705SXin Li // { 4, 5, 6 }
74*67e74705SXin Li //
75*67e74705SXin Li // CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 1
76*67e74705SXin Li //
77*67e74705SXin Li // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
78*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
79*67e74705SXin Li // CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_0]], i64 1
80*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
81*67e74705SXin Li // CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_1]], i64 1
82*67e74705SXin Li // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
83*67e74705SXin Li //
84*67e74705SXin Li // And the rest.
85*67e74705SXin Li //
86*67e74705SXin Li // CHECK: %[[S_2:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 1
87*67e74705SXin Li // CHECK: %[[S_2_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[S_2]] to %[[S]]*
88*67e74705SXin Li //
89*67e74705SXin Li // CHECK: %[[REST:.*]] = sub i64 %[[ELTS]], 6
90*67e74705SXin Li // CHECK: icmp eq i64 %[[REST]], 0
91*67e74705SXin Li // CHECK: br i1
92*67e74705SXin Li //
93*67e74705SXin Li // CHECK: %[[END:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_2_AS_S]], i64 %[[REST]]
94*67e74705SXin Li // CHECK: br label
95*67e74705SXin Li //
96*67e74705SXin Li // CHECK: %[[CUR:.*]] = phi %[[S]]* [ %[[S_2_AS_S]], {{.*}} ], [ %[[NEXT:.*]], {{.*}} ]
97*67e74705SXin Li // CHECK: call void @_ZN1SC1Ev(%[[S]]* %[[CUR]])
98*67e74705SXin Li // CHECK: %[[NEXT]] = getelementptr inbounds %[[S]], %[[S]]* %[[CUR]], i64 1
99*67e74705SXin Li // CHECK: icmp eq %[[S]]* %[[NEXT]], %[[END]]
100*67e74705SXin Li // CHECK: br i1
101*67e74705SXin Li //
102*67e74705SXin Li // CHECK: }
103*67e74705SXin Li 
104*67e74705SXin Li struct T { int a; };
105*67e74705SXin Li void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
106*67e74705SXin Li 
107*67e74705SXin Li // CHECK-LABEL: define
108*67e74705SXin Li //
109*67e74705SXin Li // CHECK: load i32, i32* @n
110*67e74705SXin Li // CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
111*67e74705SXin Li // CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
112*67e74705SXin Li //
113*67e74705SXin Li // No cookie.
114*67e74705SXin Li // CHECK-NOT: @llvm.uadd.with.overflow
115*67e74705SXin Li //
116*67e74705SXin Li // CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}})
117*67e74705SXin Li //
118*67e74705SXin Li // CHECK: %[[START_AS_T:.*]] = bitcast i8* %[[ALLOC]] to %[[T:.*]]*
119*67e74705SXin Li //
120*67e74705SXin Li // Explicit initializers:
121*67e74705SXin Li //
122*67e74705SXin Li // { 1, 2, 3 }
123*67e74705SXin Li //
124*67e74705SXin Li // CHECK: %[[T_0:.*]] = bitcast %[[T]]* %[[START_AS_T]] to [3 x %[[T]]]*
125*67e74705SXin Li //
126*67e74705SXin Li // CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_0]], i64 0, i64 0
127*67e74705SXin Li // CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_0]], i32 0, i32 0
128*67e74705SXin Li // CHECK: store i32 1, i32* %[[T_0_0_0]]
129*67e74705SXin Li // CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_0]], i64 1
130*67e74705SXin Li // CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_1]], i32 0, i32 0
131*67e74705SXin Li // CHECK: store i32 2, i32* %[[T_0_1_0]]
132*67e74705SXin Li // CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_1]], i64 1
133*67e74705SXin Li // CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_2]], i32 0, i32 0
134*67e74705SXin Li // CHECK: store i32 3, i32* %[[T_0_2_0]]
135*67e74705SXin Li //
136*67e74705SXin Li // { 4, 5, 6 }
137*67e74705SXin Li //
138*67e74705SXin Li // CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_0]], i64 1
139*67e74705SXin Li //
140*67e74705SXin Li // CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_1]], i64 0, i64 0
141*67e74705SXin Li // CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_0]], i32 0, i32 0
142*67e74705SXin Li // CHECK: store i32 4, i32* %[[T_1_0_0]]
143*67e74705SXin Li // CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_0]], i64 1
144*67e74705SXin Li // CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_1]], i32 0, i32 0
145*67e74705SXin Li // CHECK: store i32 5, i32* %[[T_1_1_0]]
146*67e74705SXin Li // CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_1]], i64 1
147*67e74705SXin Li // CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_2]], i32 0, i32 0
148*67e74705SXin Li // CHECK: store i32 6, i32* %[[T_1_2_0]]
149*67e74705SXin Li //
150*67e74705SXin Li // And the rest gets memset to 0.
151*67e74705SXin Li //
152*67e74705SXin Li // CHECK: %[[T_2:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_1]], i64 1
153*67e74705SXin Li // CHECK: %[[T_2_AS_T:.*]] = bitcast [3 x %[[T]]]* %[[T_2]] to %[[T]]*
154*67e74705SXin Li //
155*67e74705SXin Li // CHECK: %[[SIZE:.*]] = sub i64 %{{.*}}, 24
156*67e74705SXin Li // CHECK: %[[REST:.*]] = bitcast %[[T]]* %[[T_2_AS_T]] to i8*
157*67e74705SXin Li // CHECK: call void @llvm.memset.p0i8.i64(i8* %[[REST]], i8 0, i64 %[[SIZE]], i32 4, i1 false)
158*67e74705SXin Li //
159*67e74705SXin Li // CHECK: }
160*67e74705SXin Li 
161