1 | // RUN: %clang_cc1 -O1 -triple wasm32-unknown-unknown -emit-llvm -o - %s \ |
2 | // RUN: | FileCheck %s |
3 | // RUN: %clang_cc1 -O1 -triple wasm64-unknown-unknown -emit-llvm -o - %s \ |
4 | // RUN: | FileCheck %s |
5 | |
6 | #define concat_(x, y) x##y |
7 | #define concat(x, y) concat_(x, y) |
8 | |
9 | #define test(T) \ |
10 | T forward(T x) { return x; } \ |
11 | void use(T x); \ |
12 | T concat(def_, T)(void); \ |
13 | void concat(test_, T)(void) { use(concat(def_, T)()); } |
14 | |
15 | struct one_field { |
16 | double d; |
17 | }; |
18 | test(one_field); |
19 | // CHECK: define double @_Z7forward9one_field(double returned %{{.*}}) |
20 | // |
21 | // CHECK: define void @_Z14test_one_fieldv() |
22 | // CHECK: %[[call:.*]] = tail call double @_Z13def_one_fieldv() |
23 | // CHECK: tail call void @_Z3use9one_field(double %[[call]]) |
24 | // CHECK: ret void |
25 | // |
26 | // CHECK: declare void @_Z3use9one_field(double) |
27 | // CHECK: declare double @_Z13def_one_fieldv() |
28 | |
29 | struct two_fields { |
30 | double d, e; |
31 | }; |
32 | test(two_fields); |
33 | // CHECK: define void @_Z7forward10two_fields(%struct.two_fields* noalias nocapture sret %{{.*}}, %struct.two_fields* byval nocapture readonly align 8 %{{.*}}) |
34 | // |
35 | // CHECK: define void @_Z15test_two_fieldsv() |
36 | // CHECK: %[[tmp:.*]] = alloca %struct.two_fields, align 8 |
37 | // CHECK: call void @_Z14def_two_fieldsv(%struct.two_fields* nonnull sret %[[tmp]]) |
38 | // CHECK: call void @_Z3use10two_fields(%struct.two_fields* byval nonnull align 8 %[[tmp]]) |
39 | // CHECK: ret void |
40 | // |
41 | // CHECK: declare void @_Z3use10two_fields(%struct.two_fields* byval align 8) |
42 | // CHECK: declare void @_Z14def_two_fieldsv(%struct.two_fields* sret) |
43 | |
44 | struct copy_ctor { |
45 | double d; |
46 | copy_ctor(copy_ctor const &); |
47 | }; |
48 | test(copy_ctor); |
49 | // CHECK: define void @_Z7forward9copy_ctor(%struct.copy_ctor* noalias sret %{{.*}}, %struct.copy_ctor* %{{.*}}) |
50 | // |
51 | // CHECK: declare %struct.copy_ctor* @_ZN9copy_ctorC1ERKS_(%struct.copy_ctor* returned, %struct.copy_ctor* dereferenceable(8)) |
52 | // |
53 | // CHECK: define void @_Z14test_copy_ctorv() |
54 | // CHECK: %[[tmp:.*]] = alloca %struct.copy_ctor, align 8 |
55 | // CHECK: call void @_Z13def_copy_ctorv(%struct.copy_ctor* nonnull sret %[[tmp]]) |
56 | // CHECK: call void @_Z3use9copy_ctor(%struct.copy_ctor* nonnull %[[tmp]]) |
57 | // CHECK: ret void |
58 | // |
59 | // CHECK: declare void @_Z3use9copy_ctor(%struct.copy_ctor*) |
60 | // CHECK: declare void @_Z13def_copy_ctorv(%struct.copy_ctor* sret) |
61 | |
62 | struct __attribute__((aligned(16))) aligned_copy_ctor { |
63 | double d, e; |
64 | aligned_copy_ctor(aligned_copy_ctor const &); |
65 | }; |
66 | test(aligned_copy_ctor); |
67 | // CHECK: define void @_Z7forward17aligned_copy_ctor(%struct.aligned_copy_ctor* noalias sret %{{.*}}, %struct.aligned_copy_ctor* %{{.*}}) |
68 | // |
69 | // CHECK: declare %struct.aligned_copy_ctor* @_ZN17aligned_copy_ctorC1ERKS_(%struct.aligned_copy_ctor* returned, %struct.aligned_copy_ctor* dereferenceable(16)) |
70 | // |
71 | // CHECK: define void @_Z22test_aligned_copy_ctorv() |
72 | // CHECK: %[[tmp:.*]] = alloca %struct.aligned_copy_ctor, align 16 |
73 | // CHECK: call void @_Z21def_aligned_copy_ctorv(%struct.aligned_copy_ctor* nonnull sret %[[tmp]]) |
74 | // CHECK: call void @_Z3use17aligned_copy_ctor(%struct.aligned_copy_ctor* nonnull %[[tmp]]) |
75 | // CHECK: ret void |
76 | // |
77 | // CHECK: declare void @_Z3use17aligned_copy_ctor(%struct.aligned_copy_ctor*) |
78 | // CHECK: declare void @_Z21def_aligned_copy_ctorv(%struct.aligned_copy_ctor* sret) |
79 | |
80 | struct empty {}; |
81 | test(empty); |
82 | // CHECK: define void @_Z7forward5empty() |
83 | // |
84 | // CHECK: define void @_Z10test_emptyv() |
85 | // CHECK: tail call void @_Z9def_emptyv() |
86 | // CHECK: tail call void @_Z3use5empty() |
87 | // CHECK: ret void |
88 | // |
89 | // CHECK: declare void @_Z3use5empty() |
90 | // CHECK: declare void @_Z9def_emptyv() |
91 | |
92 | struct one_bitfield { |
93 | int d : 3; |
94 | }; |
95 | test(one_bitfield); |
96 | // CHECK: define i32 @_Z7forward12one_bitfield(i32 returned %{{.*}}) |
97 | // |
98 | // CHECK: define void @_Z17test_one_bitfieldv() |
99 | // CHECK: %[[call:.*]] = tail call i32 @_Z16def_one_bitfieldv() |
100 | // CHECK: tail call void @_Z3use12one_bitfield(i32 %[[call]]) |
101 | // CHECK: ret void |
102 | // |
103 | // CHECK: declare void @_Z3use12one_bitfield(i32) |
104 | // CHECK: declare i32 @_Z16def_one_bitfieldv() |
105 | |