// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fobjc-runtime=gnustep-2.2 -fobjc-dispatch-method=non-legacy -emit-llvm -o - %s | FileCheck %s // Pass and return for type size <= 8 bytes. struct S1 { int a[2]; }; // Pass and return hfa <= 8 bytes struct F1 { float a[2]; }; // Pass and return for type size > 16 bytes. struct S2 { int a[5]; }; // Pass and return aggregate (of size < 16 bytes) with non-trivial destructor. // Sret and inreg: Returned in x0 struct S3 { int a[3]; ~S3(); }; S3::~S3() { } @interface MsgTest { id isa; } @end @implementation MsgTest - (S1) smallS1 { S1 x; x.a[0] = 0; x.a[1] = 1; return x; } - (F1) smallF1 { F1 x; x.a[0] = 0.2f; x.a[1] = 0.5f; return x; } - (S2) stretS2 { S2 x; for (int i = 0; i < 5; i++) { x.a[i] = i; } return x; } - (S3) stretInRegS3 { S3 x; for (int i = 0; i < 3; i++) { x.a[i] = i; } return x; } + (S3) msgTestStretInRegS3 { S3 x; for (int i = 0; i < 3; i++) { x.a[i] = i; } return x; } @end void test0(MsgTest *t) { // CHECK: call {{.*}} @objc_msgSend S1 ret = [t smallS1]; // CHECK: call {{.*}} @objc_msgSend F1 ret2 = [t smallF1]; // CHECK: call {{.*}} @objc_msgSend_stret S2 ret3 = [t stretS2]; // CHECK: call {{.*}} @objc_msgSend_stret2 S3 ret4 = [t stretInRegS3]; // CHECK: call {{.*}} @objc_msgSend_stret2 S3 ret5 = [MsgTest msgTestStretInRegS3]; }