108 lines
2.3 KiB
C++
108 lines
2.3 KiB
C++
|
// RUN: %clang_cc1 -std=c++1z -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s
|
||
|
|
||
|
struct A {
|
||
|
A(int);
|
||
|
A(A&&);
|
||
|
A(const A&);
|
||
|
~A();
|
||
|
|
||
|
operator bool();
|
||
|
|
||
|
int arr[10];
|
||
|
};
|
||
|
|
||
|
A f();
|
||
|
void h();
|
||
|
|
||
|
// CHECK-LABEL: define {{.*}} @_Z1gv(
|
||
|
void g() {
|
||
|
// CHECK: %[[A:.*]] = alloca
|
||
|
// CHECK-NOT: alloca
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK: call {{.*}} @_Z1fv({{.*}}* sret({{.*}}) align 4 %[[A]])
|
||
|
A a = A( A{ f() } );
|
||
|
// CHECK-NOT: call
|
||
|
|
||
|
// CHECK: call void @_Z1hv(
|
||
|
h();
|
||
|
// CHECK-NOT: call
|
||
|
|
||
|
// CHECK: call void @_ZN1AD1Ev({{.*}}* {{[^,]*}} %[[A]])
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK-LABEL: }
|
||
|
}
|
||
|
|
||
|
void f(A);
|
||
|
|
||
|
// CHECK-LABEL: define {{.*}} @_Z1hv(
|
||
|
void h() {
|
||
|
// CHECK: %[[A:.*]] = alloca
|
||
|
// CHECK-NOT: alloca
|
||
|
// CHECK-NOT: call
|
||
|
|
||
|
// CHECK: call {{.*}} @_Z1fv({{.*}}* sret({{.*}}) align 4 %[[A]])
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK: call {{.*}} @_Z1f1A({{.*}}* %[[A]])
|
||
|
f(f());
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK: call void @_ZN1AD1Ev({{.*}}* {{[^,]*}} %[[A]])
|
||
|
|
||
|
// CHECK: call void @_Z1hv(
|
||
|
h();
|
||
|
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK-LABEL: }
|
||
|
}
|
||
|
|
||
|
// We still pass classes with trivial copy/move constructors and destructors in
|
||
|
// registers, even if the copy is formally omitted.
|
||
|
struct B {
|
||
|
B(int);
|
||
|
int n;
|
||
|
};
|
||
|
|
||
|
B fB();
|
||
|
void fB(B);
|
||
|
|
||
|
// CHECK-LABEL: define {{.*}} @_Z1iv(
|
||
|
void i() {
|
||
|
// CHECK: %[[B:.*]] = alloca
|
||
|
// CHECK-NOT: alloca
|
||
|
// CHECK-NOT: call
|
||
|
|
||
|
// CHECK: %[[B_N:.*]] = call i32 @_Z2fBv()
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK: store i32 %[[B_N]],
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK: %[[B_N:.*]] = load i32
|
||
|
// CHECK-NOT: call
|
||
|
// CHECK: call void @_Z2fB1B(i32 %[[B_N]])
|
||
|
fB(fB());
|
||
|
|
||
|
// CHECK-LABEL: }
|
||
|
}
|
||
|
|
||
|
// CHECK-LABEL: define {{.*}} @_Z1jv(
|
||
|
void j() {
|
||
|
// CHECK: alloca %{{.*}}*
|
||
|
// CHECK: %[[OUTERTEMP:.*]] = alloca %{{.*}}
|
||
|
// CHECK: %[[INNERTEMP:.*]] = alloca %{{.*}}
|
||
|
// CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[INNERTEMP]], i32 1)
|
||
|
// CHECK: call zeroext i1 @_ZN1AcvbEv(%{{.*}} %[[INNERTEMP]])
|
||
|
// CHECK: br i1
|
||
|
//
|
||
|
// CHECK: call void @_ZN1AC1EOS_(%{{.*}} %[[OUTERTEMP]], %{{.*}} %[[INNERTEMP]])
|
||
|
// CHECK: br label
|
||
|
//
|
||
|
// CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[OUTERTEMP]], i32 2)
|
||
|
// CHECK: br label
|
||
|
//
|
||
|
// CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[INNERTEMP]])
|
||
|
A &&a = A(1) ?: A(2);
|
||
|
|
||
|
// CHECK: call void @_Z1iv()
|
||
|
i();
|
||
|
|
||
|
// CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[OUTERTEMP]])
|
||
|
}
|