// RUN: %clang_cc1 -no-opaque-pointers -triple aarch64-windows -ffreestanding -emit-llvm -O0 \
// RUN: -x c++ -o - %s | FileCheck %s
// Pass and return for type size <= 8 bytes.
// CHECK: define {{.*}} i64 @{{.*}}f1{{.*}}()
// CHECK: call i64 {{.*}}func1{{.*}}(i64 %3)
;
S1 ;
S1
// Pass and return type size <= 16 bytes.
// CHECK: define {{.*}} [2 x i64] @{{.*}}f2{{.*}}()
// CHECK: call [2 x i64] {{.*}}func2{{.*}}([2 x i64] %3)
;
S2 ;
S2
// Pass and return for type size > 16 bytes.
// CHECK: define {{.*}} void @{{.*}}f3{{.*}}(%struct.S3* noalias sret(%struct.S3) align 4 %agg.result)
// CHECK: call void {{.*}}func3{{.*}}(%struct.S3* sret(%struct.S3) align 4 %agg.result, %struct.S3* noundef %agg.tmp)
;
S3 ;
S3
// Pass and return aggregate (of size < 16 bytes) with non-trivial destructor.
// Passed directly but returned indirectly.
// CHECK: define {{.*}} void {{.*}}f4{{.*}}(%struct.S4* inreg noalias sret(%struct.S4) align 4 %agg.result)
// CHECK: call void {{.*}}func4{{.*}}(%struct.S4* inreg sret(%struct.S4) align 4 %agg.result, [2 x i64] %5)
;
S4 ;
S4
// Pass and return from instance method called from instance method.
// CHECK: define {{.*}} void @{{.*}}bar@Q1{{.*}}(%class.Q1* {{[^,]*}} %this, %class.P1* inreg noalias sret(%class.P1) align 1 %agg.result)
// CHECK: call void {{.*}}foo@P1{{.*}}(%class.P1* noundef{{[^,]*}} %ref.tmp, %class.P1* inreg sret(%class.P1) align 1 %agg.result, i8 %1)
;
;
P1
// Pass and return from instance method called from free function.
// CHECK: define {{.*}} void {{.*}}bar{{.*}}()
// CHECK: call void {{.*}}foo@P2{{.*}}(%class.P2* noundef{{[^,]*}} %ref.tmp, %class.P2* inreg sret(%class.P2) align 1 %retval, i8 %0)
;
P2
// Pass and return an object with a user-provided constructor (passed directly,
// returned indirectly)
// CHECK: define {{.*}} void @{{.*}}f5{{.*}}(%struct.S5* inreg noalias sret(%struct.S5) align 4 %agg.result)
// CHECK: call void {{.*}}func5{{.*}}(%struct.S5* inreg sret(%struct.S5) align 4 %agg.result, i64 {{.*}})
;
S5 ;
S5
// Pass and return an object with a non-trivial explicitly defaulted constructor
// (passed directly, returned directly)
// CHECK: define {{.*}} i8 @"?f6@@YA?AUS6@@XZ"()
// CHECK: call i8 {{.*}}func6{{.*}}(i64 {{.*}})
;
;
S6 ;
S6
// Pass and return an object with a non-trivial implicitly defaulted constructor
// (passed directly, returned directly)
// CHECK: define {{.*}} i8 @"?f7@@YA?AUS7@@XZ"()
// CHECK: call i8 {{.*}}func7{{.*}}(i64 {{.*}})
;
S7 ;
S7
;
// Pass and return an object with a non-trivial default destructor (passed
// directly, returne indirectly)
;
// CHECK: define {{.*}} void {{.*}}?f8{{.*}}(%struct.S8* inreg noalias sret(%struct.S8) align 4 {{.*}})
// CHECK: call void {{.*}}func8{{.*}}(%struct.S8* inreg sret(%struct.S8) align 4 {{.*}}, i64 {{.*}})
S8 ;
S8
// Pass and return an object with a non-trivial copy-assignment operator and
// a trivial copy constructor (passed directly, returned indirectly)
// CHECK: define {{.*}} void @"?f9@@YA?AUS9@@XZ"(%struct.S9* inreg noalias sret(%struct.S9) align 4 {{.*}})
// CHECK: call void {{.*}}func9{{.*}}(%struct.S9* inreg sret(%struct.S9) align 4 {{.*}}, i64 {{.*}})
;
S9 ;
S9
// Pass and return an object with a base class (passed directly, returned
// indirectly).
// CHECK: define dso_local void {{.*}}f10{{.*}}(%struct.S10* inreg noalias sret(%struct.S10) align 4 {{.*}})
// CHECK: call void {{.*}}func10{{.*}}(%struct.S10* inreg sret(%struct.S10) align 4 {{.*}}, [2 x i64] {{.*}})
;
S10 ;
S10
// Pass and return a non aggregate object exceeding > 128 bits (passed
// indirectly, returned indirectly)
// CHECK: define dso_local void {{.*}}f11{{.*}}(%struct.S11* inreg noalias sret(%struct.S11) align 8 {{.*}})
// CHECK: call void {{.*}}func11{{.*}}(%struct.S11* inreg sret(%struct.S11) align 8 {{.*}}, %struct.S11* {{.*}})
;
S11 ;
S11