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( 18 void g() { 19 // CHECK: %[[A:.*]] = alloca 20 // CHECK-NOT: alloca 21 // CHECK-NOT: call 22 // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[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( 38 void h() { 39 // CHECK: %[[A:.*]] = alloca 40 // CHECK-NOT: alloca 41 // CHECK-NOT: call 42 43 // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[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( 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( 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