1 // Covers a bug fix for ABI selection with homogenous aggregates:
2 //  See: https://bugs.llvm.org/show_bug.cgi?id=39982
3 
4 // REQUIRES: arm-registered-target
5 // RUN: %clang -mfloat-abi=hard --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=HARD,CHECK
6 // RUN: %clang -mfloat-abi=softfp --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=SOFTFP,CHECK
7 // RUN: %clang -mfloat-abi=soft --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=SOFT,CHECK
8 
9 struct S {
10   float f;
11   float d;
12   float c;
13   float t;
14 };
15 
16 // Variadic functions should always marshal for the base standard.
17 // See section 5.5 (Parameter Passing) of the AAPCS.
variadic(S s,...)18 float __attribute__((pcs("aapcs-vfp"))) variadic(S s, ...) {
19   // CHECK-NOT: vmov s{{[0-9]+}}, s{{[0-9]+}}
20   // CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
21   return s.d;
22 }
23 
no_attribute(S s)24 float no_attribute(S s) {
25   // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
26   // SOFTFP: mov r{{[0-9]+}}, r{{[0-9]+}}
27   // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
28   return s.d;
29 }
30 
baz(float x,float y)31 float __attribute__((pcs("aapcs-vfp"))) baz(float x, float y) {
32   // CHECK-NOT: mov s{{[0-9]+}}, r{{[0-9]+}}
33   // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
34   // SOFTFP: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
35   // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
36   return y;
37 }
38 
foo(S s)39 float __attribute__((pcs("aapcs-vfp"))) foo(S s) {
40   // CHECK-NOT: mov s{{[0-9]+}}, r{{[0-9]+}}
41   // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
42   // SOFTFP: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
43   // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
44   return s.d;
45 }
46 
bar(S s)47 float __attribute__((pcs("aapcs"))) bar(S s) {
48   // CHECK-NOT: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
49   // CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
50   return s.d;
51 }
52