summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/wasm-args-returns.cpp
blob: 24adc8e08761de71feb26d974ba5b7b07d769329 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// RUN: %clang_cc1 -O1 -triple wasm32-unknown-unknown -emit-llvm -o - %s \
// RUN:   | FileCheck %s
// RUN: %clang_cc1 -O1 -triple wasm64-unknown-unknown -emit-llvm -o - %s \
// RUN:   | FileCheck %s

#define concat_(x, y) x ## y
#define concat(x, y) concat_(x, y)

#define test(T) \
  T forward(T x) { return x; } \
  void use(T x); \
  T concat(def_, T)(void); \
  void concat(test_, T)(void) { use(concat(def_, T)()); }

struct one_field { double d; };
test(one_field);
// CHECK: define double @_Z7forward9one_field(double returned %{{.*}})
//
// CHECK: define void @_Z14test_one_fieldv()
// CHECK: %[[call:.*]] = tail call double @_Z13def_one_fieldv()
// CHECK: tail call void @_Z3use9one_field(double %[[call]])
// CHECK: ret void
//
// CHECK: declare void @_Z3use9one_field(double)
// CHECK: declare double @_Z13def_one_fieldv()

struct two_fields { double d, e; };
test(two_fields);
// CHECK: define void @_Z7forward10two_fields(%struct.two_fields* noalias nocapture sret %{{.*}}, %struct.two_fields* byval nocapture readonly align 8 %{{.*}})
//
// CHECK: define void @_Z15test_two_fieldsv()
// CHECK: %[[tmp:.*]] = alloca %struct.two_fields, align 8
// CHECK: call void @_Z14def_two_fieldsv(%struct.two_fields* nonnull sret %[[tmp]])
// CHECK: call void @_Z3use10two_fields(%struct.two_fields* byval nonnull align 8 %[[tmp]])
// CHECK: ret void
//
// CHECK: declare void @_Z3use10two_fields(%struct.two_fields* byval align 8)
// CHECK: declare void @_Z14def_two_fieldsv(%struct.two_fields* sret)

struct copy_ctor {
    double d;
    copy_ctor(copy_ctor const&);
};
test(copy_ctor);
// CHECK: define void @_Z7forward9copy_ctor(%struct.copy_ctor* noalias sret %{{.*}}, %struct.copy_ctor* %{{.*}})
//
// CHECK: declare %struct.copy_ctor* @_ZN9copy_ctorC1ERKS_(%struct.copy_ctor* returned, %struct.copy_ctor* dereferenceable(8))
//
// CHECK: define void @_Z14test_copy_ctorv()
// CHECK: %[[tmp:.*]] = alloca %struct.copy_ctor, align 8
// CHECK: call void @_Z13def_copy_ctorv(%struct.copy_ctor* nonnull sret %[[tmp]])
// CHECK: call void @_Z3use9copy_ctor(%struct.copy_ctor* nonnull %[[tmp]])
// CHECK: ret void
//
// CHECK: declare void @_Z3use9copy_ctor(%struct.copy_ctor*)
// CHECK: declare void @_Z13def_copy_ctorv(%struct.copy_ctor* sret)

struct __attribute__((aligned(16))) aligned_copy_ctor {
    double d, e;
    aligned_copy_ctor(aligned_copy_ctor const&);
};
test(aligned_copy_ctor);
// CHECK: define void @_Z7forward17aligned_copy_ctor(%struct.aligned_copy_ctor* noalias sret %{{.*}}, %struct.aligned_copy_ctor* %{{.*}})
//
// CHECK: declare %struct.aligned_copy_ctor* @_ZN17aligned_copy_ctorC1ERKS_(%struct.aligned_copy_ctor* returned, %struct.aligned_copy_ctor* dereferenceable(16))
//
// CHECK: define void @_Z22test_aligned_copy_ctorv()
// CHECK: %[[tmp:.*]] = alloca %struct.aligned_copy_ctor, align 16
// CHECK: call void @_Z21def_aligned_copy_ctorv(%struct.aligned_copy_ctor* nonnull sret %[[tmp]])
// CHECK: call void @_Z3use17aligned_copy_ctor(%struct.aligned_copy_ctor* nonnull %[[tmp]])
// CHECK: ret void
//
// CHECK: declare void @_Z3use17aligned_copy_ctor(%struct.aligned_copy_ctor*)
// CHECK: declare void @_Z21def_aligned_copy_ctorv(%struct.aligned_copy_ctor* sret)

struct empty {};
test(empty);
// CHECK: define void @_Z7forward5empty()
//
// CHECK: define void @_Z10test_emptyv()
// CHECK: tail call void @_Z9def_emptyv()
// CHECK: tail call void @_Z3use5empty()
// CHECK: ret void
//
// CHECK: declare void @_Z3use5empty()
// CHECK: declare void @_Z9def_emptyv()

struct one_bitfield {
    int d:3;
};
test(one_bitfield);
// CHECK: define i32 @_Z7forward12one_bitfield(i32 returned %{{.*}})
//
// CHECK: define void @_Z17test_one_bitfieldv()
// CHECK: %[[call:.*]] = tail call i32 @_Z16def_one_bitfieldv()
// CHECK: tail call void @_Z3use12one_bitfield(i32 %[[call]])
// CHECK: ret void
//
// CHECK: declare void @_Z3use12one_bitfield(i32)
// CHECK: declare i32 @_Z16def_one_bitfieldv()