@@ -9,7 +9,10 @@ void fn() {
9
9
a ();
10
10
}
11
11
12
+ // CHECK-DAG: !ty_A = !cir.struct<struct "A" {!s32i}>
12
13
// CHECK: !ty_anon2E0_ = !cir.struct<class "anon.0" {!u8i}>
14
+ // CHECK-DAG: !ty_anon2E7_ = !cir.struct<class "anon.7" {!ty_A}>
15
+ // CHECK-DAG: !ty_anon2E8_ = !cir.struct<class "anon.8" {!cir.ptr<!ty_A>}>
13
16
// CHECK-DAG: module
14
17
15
18
// CHECK: cir.func lambda internal private @_ZZ2fnvENK3$_0clEv{{.*}}) extra
@@ -18,9 +21,8 @@ void fn() {
18
21
// CHECK-NEXT: %0 = cir.alloca !ty_anon2E0_, !cir.ptr<!ty_anon2E0_>, ["a"]
19
22
// CHECK: cir.call @_ZZ2fnvENK3$_0clEv
20
23
21
- // LLVM: {{.*}}void @"_ZZ2fnvENK3$_0clEv"(ptr [[THIS:%.*]])
22
- // FIXME: argument attributes should be emmitted, and lambda's alignment
23
- // COM: LLVM: {{.*}} @"_ZZ2fnvENK3$_0clEv"(ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]){{%.*}} align 2 {
24
+ // LLVM-LABEL: _ZZ2fnvENK3$_0clEv
25
+ // LLVM-SAME: (ptr [[THIS:%.*]])
24
26
// LLVM: [[THIS_ADDR:%.*]] = alloca ptr, i64 1, align 8
25
27
// LLVM: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
26
28
// LLVM: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
@@ -53,9 +55,10 @@ void l0() {
53
55
// CHECK: %8 = cir.load %7 : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
54
56
// CHECK: cir.store %6, %8 : !s32i, !cir.ptr<!s32i>
55
57
56
- // CHECK: cir.func @ _Z2l0v()
58
+ // CHECK-LABEL: _Z2l0v
57
59
58
- // LLVM: {{.* }}void @"_ZZ2l0vENK3$_0clEv"(ptr [[THIS:%.*]])
60
+ // LLVM-LABEL: _ZZ2l0vENK3$_0clEv
61
+ // LLVM-SAME: (ptr [[THIS:%.*]])
59
62
// LLVM: [[THIS_ADDR:%.*]] = alloca ptr, i64 1, align 8
60
63
// LLVM: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
61
64
// LLVM: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
@@ -91,7 +94,7 @@ auto g() {
91
94
};
92
95
}
93
96
94
- // CHECK: cir.func @_Z1gv() -> !ty_anon2E3_
97
+ // CHECK-LABEL: @_Z1gv()
95
98
// CHECK: %0 = cir.alloca !ty_anon2E3_, !cir.ptr<!ty_anon2E3_>, ["__retval"] {alignment = 8 : i64}
96
99
// CHECK: %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}
97
100
// CHECK: %2 = cir.const #cir.int<12> : !s32i
@@ -120,7 +123,7 @@ auto g2() {
120
123
}
121
124
122
125
// Should be same as above because of NRVO
123
- // CHECK: cir.func @_Z2g2v() -> !ty_anon2E4_
126
+ // CHECK-LABEL: @_Z2g2v()
124
127
// CHECK-NEXT: %0 = cir.alloca !ty_anon2E4_, !cir.ptr<!ty_anon2E4_>, ["__retval", init] {alignment = 8 : i64}
125
128
// CHECK-NEXT: %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}
126
129
// CHECK-NEXT: %2 = cir.const #cir.int<12> : !s32i
@@ -143,7 +146,7 @@ int f() {
143
146
return g2 ()();
144
147
}
145
148
146
- // CHECK: cir.func @_Z1fv() -> !s32i
149
+ // CHECK-LABEL: @_Z1fv()
147
150
// CHECK-NEXT: %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
148
151
// CHECK-NEXT: cir.scope {
149
152
// CHECK-NEXT: %2 = cir.alloca !ty_anon2E4_, !cir.ptr<!ty_anon2E4_>, ["ref.tmp0"] {alignment = 8 : i64}
@@ -156,7 +159,8 @@ int f() {
156
159
// CHECK-NEXT: cir.return %1 : !s32i
157
160
// CHECK-NEXT: }
158
161
159
- // LLVM: {{.*}}i32 @"_ZZ2g2vENK3$_0clEv"(ptr [[THIS:%.*]])
162
+ // LLVM-LABEL: _ZZ2g2vENK3$_0clEv
163
+ // LLVM-SAME: (ptr [[THIS:%.*]])
160
164
// LLVM: [[THIS_ADDR:%.*]] = alloca ptr, i64 1, align 8
161
165
// LLVM: [[I_SAVE:%.*]] = alloca i32, i64 1, align 4
162
166
// LLVM: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
@@ -201,7 +205,7 @@ int g3() {
201
205
// lambda operator int (*)(int const&)()
202
206
// CHECK: cir.func internal private @_ZZ2g3vENK3$_0cvPFiRKiEEv
203
207
204
- // CHECK: cir.func @_Z2g3v() -> !s32i
208
+ // CHECK-LABEL: @_Z2g3v()
205
209
// CHECK: %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
206
210
// CHECK: %1 = cir.alloca !cir.ptr<!cir.func<!s32i (!cir.ptr<!s32i>)>>, !cir.ptr<!cir.ptr<!cir.func<!s32i (!cir.ptr<!s32i>)>>>, ["fn", init] {alignment = 8 : i64}
207
211
// CHECK: %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["task", init] {alignment = 4 : i64}
@@ -230,12 +234,14 @@ int g3() {
230
234
// CHECK: }
231
235
232
236
// lambda operator()
237
+ // LLVM-LABEL: _ZZ2g3vENK3$_0clERKi
233
238
// FIXME: argument attributes should be emitted
234
- // COM: LLVM: define internal noundef i32 @"_ZZ2g3vENK3$_0clERKi" (ptr noundef nonnull align 1 dereferenceable(1) {{%.*}}, ptr noundef nonnull align 4 dereferenceable(4){{%.*}}) #0 align 2
235
- // LLVM: {{.*}}i32 @"_ZZ2g3vENK3$_0clERKi"( ptr {{%.*}}, ptr {{%.*}})
239
+ // COM: LLVM-SAME: (ptr noundef nonnull align 1 dereferenceable(1) {{%.*}},
240
+ // COM: LLVM-SAME: ptr noundef nonnull align 4 dereferenceable(4) {{%.*}}) #0 align 2
236
241
237
242
// lambda __invoke()
238
- // LLVM: {{.*}}i32 @"_ZZ2g3vEN3$_08__invokeERKi"(ptr [[i:%.*]])
243
+ // LLVM-LABEL: _ZZ2g3vEN3$_08__invokeERKi
244
+ // LLVM-SAME: (ptr [[i:%.*]])
239
245
// LLVM: [[i_addr:%.*]] = alloca ptr, i64 1, align 8
240
246
// LLVM: [[ret_val:%.*]] = alloca i32, i64 1, align 4
241
247
// LLVM: [[unused_capture:%.*]] = alloca %class.anon.5, i64 1, align 1
@@ -285,3 +291,104 @@ int g3() {
285
291
// LLVM: store i32 [[tmp2]], ptr [[ret_val]], align 4
286
292
// LLVM: [[tmp3:%.*]] = load i32, ptr [[ret_val]], align 4
287
293
// LLVM: ret i32 [[tmp3]]
294
+
295
+ struct A {
296
+ int a = 111 ;
297
+ int foo () { return [*this ] { return a; }(); }
298
+ int bar () { return [this ] { return a; }(); }
299
+ };
300
+ // A's default ctor
301
+ // CHECK-LABEL: _ZN1AC1Ev
302
+
303
+ // lambda operator() in foo()
304
+ // CHECK-LABEL: _ZZN1A3fooEvENKUlvE_clEv
305
+ // CHECK-SAME: ([[ARG:%.*]]: !cir.ptr<!ty_anon2E7_>
306
+ // CHECK: [[ARG_ADDR:%.*]] = cir.alloca !cir.ptr<!ty_anon2E7_>, !cir.ptr<!cir.ptr<!ty_anon2E7_>>, ["this", init] {alignment = 8 : i64}
307
+ // CHECK: [[RETVAL_ADDR:%.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
308
+ // CHECK: cir.store [[ARG]], [[ARG_ADDR]] : !cir.ptr<!ty_anon2E7_>, !cir.ptr<!cir.ptr<!ty_anon2E7_>>
309
+ // CHECK: [[CLS_ANNO7:%.*]] = cir.load [[ARG_ADDR]] : !cir.ptr<!cir.ptr<!ty_anon2E7_>>, !cir.ptr<!ty_anon2E7_>
310
+ // CHECK: [[STRUCT_A:%.*]] = cir.get_member [[CLS_ANNO7]][0] {name = "this"} : !cir.ptr<!ty_anon2E7_> -> !cir.ptr<!ty_A>
311
+ // CHECK: [[a:%.*]] = cir.get_member [[STRUCT_A]][0] {name = "a"} : !cir.ptr<!ty_A> -> !cir.ptr<!s32i> loc(#loc70)
312
+ // CHECK: [[TMP0:%.*]] = cir.load [[a]] : !cir.ptr<!s32i>, !s32i
313
+ // CHECK: cir.store [[TMP0]], [[RETVAL_ADDR]] : !s32i, !cir.ptr<!s32i>
314
+ // CHECK: [[RET_VAL:%.*]] = cir.load [[RETVAL_ADDR]] : !cir.ptr<!s32i>,
315
+ // CHECK: cir.return [[RET_VAL]] : !s32i
316
+
317
+ // LLVM-LABEL: @_ZZN1A3fooEvENKUlvE_clEv
318
+ // LLVM-SAME: (ptr [[ARG:%.*]])
319
+ // LLVM: [[ARG_ADDR:%.*]] = alloca ptr, i64 1, align 8
320
+ // LLVM: [[RET:%.*]] = alloca i32, i64 1, align 4
321
+ // LLVM: store ptr [[ARG]], ptr [[ARG_ADDR]], align 8
322
+ // LLVM: [[CLS_ANNO7:%.*]] = load ptr, ptr [[ARG_ADDR]], align 8
323
+ // LLVM: [[STRUCT_A:%.*]] = getelementptr %class.anon.7, ptr [[CLS_ANNO7]], i32 0, i32 0
324
+ // LLVM: [[a:%.*]] = getelementptr %struct.A, ptr [[STRUCT_A]], i32 0, i32 0
325
+ // LLVM: [[TMP0:%.*]] = load i32, ptr [[a]], align 4
326
+ // LLVM: store i32 [[TMP0]], ptr [[RET]], align 4
327
+ // LLVM: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4
328
+ // LLVM: ret i32 [[TMP1]]
329
+
330
+ // A::foo()
331
+ // CHECK-LABEL: @_ZN1A3fooEv
332
+ // CHECK: [[THIS_ARG:%.*]] = cir.alloca !ty_anon2E7_, !cir.ptr<!ty_anon2E7_>, ["ref.tmp0"] {alignment = 4 : i64}
333
+ // CHECK: cir.call @_ZZN1A3fooEvENKUlvE_clEv([[THIS_ARG]]) : (!cir.ptr<!ty_anon2E7_>) -> !s32i
334
+
335
+ // LLVM-LABEL: _ZN1A3fooEv
336
+ // LLVM: [[this_in_foo:%.*]] = alloca %class.anon.7, i64 1, align 4
337
+ // LLVM: call i32 @_ZZN1A3fooEvENKUlvE_clEv(ptr [[this_in_foo]])
338
+
339
+ // lambda operator() in bar()
340
+ // CHECK-LABEL: _ZZN1A3barEvENKUlvE_clEv
341
+ // CHECK-SAME: ([[ARG2:%.*]]: !cir.ptr<!ty_anon2E8_>
342
+ // CHECK: [[ARG2_ADDR:%.*]] = cir.alloca !cir.ptr<!ty_anon2E8_>, !cir.ptr<!cir.ptr<!ty_anon2E8_>>, ["this", init] {alignment = 8 : i64}
343
+ // CHECK: [[RETVAL_ADDR:%.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
344
+ // CHECK: cir.store [[ARG2]], [[ARG2_ADDR]] : !cir.ptr<!ty_anon2E8_>, !cir.ptr<!cir.ptr<!ty_anon2E8_>>
345
+ // CHECK: [[CLS_ANNO8:%.*]] = cir.load [[ARG2_ADDR]] : !cir.ptr<!cir.ptr<!ty_anon2E8_>>, !cir.ptr<!ty_anon2E8_>
346
+ // CHECK: [[STRUCT_A_PTR:%.*]] = cir.get_member [[CLS_ANNO8]][0] {name = "this"} : !cir.ptr<!ty_anon2E8_> -> !cir.ptr<!cir.ptr<!ty_A>>
347
+ // CHECK: [[STRUCT_A:%.*]] = cir.load [[STRUCT_A_PTR]] : !cir.ptr<!cir.ptr<!ty_A>>, !cir.ptr<!ty_A>
348
+ // CHECK: [[a:%.*]] = cir.get_member [[STRUCT_A]][0] {name = "a"} : !cir.ptr<!ty_A> -> !cir.ptr<!s32i> loc(#loc70)
349
+ // CHECK: [[TMP0:%.*]] = cir.load [[a]] : !cir.ptr<!s32i>, !s32i
350
+ // CHECK: cir.store [[TMP0]], [[RETVAL_ADDR]] : !s32i, !cir.ptr<!s32i>
351
+ // CHECK: [[RET_VAL:%.*]] = cir.load [[RETVAL_ADDR]] : !cir.ptr<!s32i>
352
+ // CHECK: cir.return [[RET_VAL]] : !s32i
353
+
354
+ // LLVM-LABEL: _ZZN1A3barEvENKUlvE_clEv
355
+ // LLVM-SAME: (ptr [[ARG2:%.*]])
356
+ // LLVM: [[ARG2_ADDR:%.*]] = alloca ptr, i64 1, align 8
357
+ // LLVM: [[RET:%.*]] = alloca i32, i64 1, align 4
358
+ // LLVM: store ptr [[ARG2]], ptr [[ARG2_ADDR]], align 8
359
+ // LLVM: [[CLS_ANNO8:%.*]] = load ptr, ptr [[ARG2_ADDR]], align 8
360
+ // LLVM: [[STRUCT_A_PTR:%.*]] = getelementptr %class.anon.8, ptr [[CLS_ANNO8]], i32 0, i32 0
361
+ // LLVM: [[STRUCT_A:%.*]] = load ptr, ptr [[STRUCT_A_PTR]], align 8
362
+ // LLVM: [[a:%.*]] = getelementptr %struct.A, ptr [[STRUCT_A]], i32
363
+ // LLVM: [[TMP0:%.*]] = load i32, ptr [[a]], align 4
364
+ // LLVM: store i32 [[TMP0]], ptr [[RET]], align 4
365
+ // LLVM: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4
366
+ // LLVM: ret i32 [[TMP1]]
367
+
368
+ // A::bar()
369
+ // CHECK-LABEL: _ZN1A3barEv
370
+ // CHECK: [[THIS_ARG:%.*]] = cir.alloca !ty_anon2E8_, !cir.ptr<!ty_anon2E8_>, ["ref.tmp0"] {alignment = 8 : i64}
371
+ // CHECK: cir.call @_ZZN1A3barEvENKUlvE_clEv([[THIS_ARG]])
372
+
373
+ // LLVM-LABEL: _ZN1A3barEv
374
+ // LLVM: [[this_in_bar:%.*]] = alloca %class.anon.8, i64 1, align 8
375
+ // LLVM: call i32 @_ZZN1A3barEvENKUlvE_clEv(ptr [[this_in_bar]])
376
+
377
+ int test_lambda_this1 (){
378
+ struct A clsA;
379
+ int x = clsA.foo ();
380
+ int y = clsA.bar ();
381
+ return x+y;
382
+ }
383
+
384
+ // CHECK-LABEL: test_lambda_this1
385
+ // Construct A
386
+ // CHECK: cir.call @_ZN1AC1Ev([[A_THIS:%.*]]) : (!cir.ptr<!ty_A>) -> ()
387
+ // CHECK: cir.call @_ZN1A3fooEv([[A_THIS]]) : (!cir.ptr<!ty_A>) -> !s32i
388
+ // CHECK: cir.call @_ZN1A3barEv([[A_THIS]]) : (!cir.ptr<!ty_A>) -> !s32i
389
+
390
+ // LLVM-LABEL: test_lambda_this1
391
+ // LLVM: [[A_THIS:%.*]] = alloca %struct.A, i64 1, align 4
392
+ // LLVM: call void @_ZN1AC1Ev(ptr [[A_THIS]])
393
+ // LLVM: call i32 @_ZN1A3fooEv(ptr [[A_THIS]])
394
+ // LLVM: call i32 @_ZN1A3barEv(ptr [[A_THIS]])
0 commit comments