1 // RUN: %clang_cc1 -std=c++1z -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s
2 
3 struct A {
4   A(int);
5   A(A&&);
6   A(const A&);
7   ~A();
8 
9   operator bool();
10 
11   int arr[10];
12 };
13 
14 A f();
15 void h();
16 
17 // CHECK-LABEL: define {{.*}} @_Z1gv(
g()18 void g() {
19   // CHECK: %[[A:.*]] = alloca
20   // CHECK-NOT: alloca
21   // CHECK-NOT: call
22   // CHECK: call {{.*}} @_Z1fv({{.*}}* sret align 4 %[[A]])
23   A a = A( A{ f() } );
24   // CHECK-NOT: call
25 
26   // CHECK: call void @_Z1hv(
27   h();
28   // CHECK-NOT: call
29 
30   // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
31   // CHECK-NOT: call
32   // CHECK-LABEL: }
33 }
34 
35 void f(A);
36 
37 // CHECK-LABEL: define {{.*}} @_Z1hv(
h()38 void h() {
39   // CHECK: %[[A:.*]] = alloca
40   // CHECK-NOT: alloca
41   // CHECK-NOT: call
42 
43   // CHECK: call {{.*}} @_Z1fv({{.*}}* sret align 4 %[[A]])
44   // CHECK-NOT: call
45   // CHECK: call {{.*}} @_Z1f1A({{.*}}* %[[A]])
46   f(f());
47   // CHECK-NOT: call
48   // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
49 
50   // CHECK: call void @_Z1hv(
51   h();
52 
53   // CHECK-NOT: call
54   // CHECK-LABEL: }
55 }
56 
57 // We still pass classes with trivial copy/move constructors and destructors in
58 // registers, even if the copy is formally omitted.
59 struct B {
60   B(int);
61   int n;
62 };
63 
64 B fB();
65 void fB(B);
66 
67 // CHECK-LABEL: define {{.*}} @_Z1iv(
i()68 void i() {
69   // CHECK: %[[B:.*]] = alloca
70   // CHECK-NOT: alloca
71   // CHECK-NOT: call
72 
73   // CHECK: %[[B_N:.*]] = call i32 @_Z2fBv()
74   // CHECK-NOT: call
75   // CHECK: store i32 %[[B_N]],
76   // CHECK-NOT: call
77   // CHECK: %[[B_N:.*]] = load i32
78   // CHECK-NOT: call
79   // CHECK: call void @_Z2fB1B(i32 %[[B_N]])
80   fB(fB());
81 
82   // CHECK-LABEL: }
83 }
84 
85 // CHECK-LABEL: define {{.*}} @_Z1jv(
j()86 void j() {
87   // CHECK:   alloca %{{.*}}*
88   // CHECK:   %[[OUTERTEMP:.*]] = alloca %{{.*}}
89   // CHECK:   %[[INNERTEMP:.*]] = alloca %{{.*}}
90   // CHECK:   call void @_ZN1AC1Ei(%{{.*}} %[[INNERTEMP]], i32 1)
91   // CHECK:   call zeroext i1 @_ZN1AcvbEv(%{{.*}} %[[INNERTEMP]])
92   // CHECK:   br i1
93   //
94   // CHECK:   call void @_ZN1AC1EOS_(%{{.*}} %[[OUTERTEMP]], %{{.*}} %[[INNERTEMP]])
95   // CHECK:   br label
96   //
97   // CHECK:   call void @_ZN1AC1Ei(%{{.*}} %[[OUTERTEMP]], i32 2)
98   // CHECK:   br label
99   //
100   // CHECK:   call void @_ZN1AD1Ev(%{{.*}} %[[INNERTEMP]])
101   A &&a = A(1) ?: A(2);
102 
103   // CHECK:   call void @_Z1iv()
104   i();
105 
106   // CHECK:   call void @_ZN1AD1Ev(%{{.*}} %[[OUTERTEMP]])
107 }
108