xref: /llvm-project/clang/test/CodeGen/homogeneous-aggregates.c (revision ceb21fa4e49ddc8478371b41250f206082c5c67e)
1 // REQUIRES: arm-registered-target,aarch64-registered-target,powerpc-registered-target
2 // RUN: %clang_cc1 -triple thumbv7-none-none -mfloat-abi hard -x c -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS
3 // RUN: %clang_cc1 -triple thumbv7-none-none -mfloat-abi hard -x c++ -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS
4 // RUN: %clang_cc1 -triple thumbv7-none-none -mfloat-abi hard -x c++ -DEXTERN_C -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS
5 // RUN: %clang_cc1 -triple aarch64-none-none -mfloat-abi hard -x c -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS
6 // RUN: %clang_cc1 -triple aarch64-none-none -mfloat-abi hard -x c++ -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS
7 // RUN: %clang_cc1 -triple aarch64-none-none -mfloat-abi hard -x c++ -DEXTERN_C -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS
8 // RUN: %clang_cc1 -triple powerpc64le-none-none -mfloat-abi hard -x c -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC --check-prefix=PPC-C
9 // RUN: %clang_cc1 -triple powerpc64le-none-none -mfloat-abi hard -x c++ -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC --check-prefix=PPC-CXX
10 // RUN: %clang_cc1 -triple powerpc64le-none-none -mfloat-abi hard -x c++ -DEXTERN_C -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC --check-prefix=PPC-CXX
11 
12 // The aim here is to test whether each of these structure types is
13 // regarded as a homogeneous aggregate of a single kind of
14 // floating-point item, because in all of these ABIs, that changes the
15 // calling convention.
16 //
17 // We expect that 'Floats' and 'Doubles' are homogeneous, and 'Mixed'
18 // is not. But the next two structures, with separating zero-size
19 // bitfields, are more interesting.
20 //
21 // For the Arm architecture, AAPCS says that the homogeneity rule is
22 // applied _after_ data layout is completed, so that it's unaffected
23 // by anything that was completely discarded during data layout. So we
24 // expect that FloatsBF and DoublesBF still count as homogeneous.
25 //
26 // But on PowerPC, it depends on whether the source language is C or
27 // C++, because that's consistent with the decisions gcc makes.
28 
29 struct Floats {
30     float a;
31     float b;
32 };
33 
34 struct Doubles {
35     double a;
36     double b;
37 };
38 
39 struct Mixed {
40     double a;
41     float b;
42 };
43 
44 struct FloatsBF {
45     float a;
46     int : 0;
47     float b;
48 };
49 
50 struct DoublesBF {
51     double a;
52     int : 0;
53     double b;
54 };
55 
56 // In C++ mode, we test both with and without extern "C", to ensure
57 // that doesn't make a difference.
58 #ifdef EXTERN_C
59 #define LINKAGE extern "C"
60 #else
61 #define LINKAGE
62 #endif
63 
64 // For Arm backends, the IR emitted for the homogeneous-aggregate
65 // return convention uses the actual structure type, so that
66 // HandleFloats returns a %struct.Floats, and so on. To check that
67 // 'Mixed' is not treated as homogeneous, it's enough to check that
68 // its return type is _not_ %struct.Mixed. (The fallback handling
69 // varies between AArch32 and AArch64.)
70 //
71 // For PowerPC, homogeneous structure types are lowered to an IR array
72 // types like [2 x float], and the non-homogeneous Mixed is lowered to
73 // a pair of i64.
74 
75 // AAPCS: define{{.*}} %struct.Floats @{{.*HandleFloats.*}}
76 // PPC: define{{.*}} [2 x float] @{{.*HandleFloats.*}}
HandleFloats(struct Floats x)77 LINKAGE struct Floats HandleFloats(struct Floats x) { return x; }
78 
79 // AAPCS: define{{.*}} %struct.Doubles @{{.*HandleDoubles.*}}
80 // PPC: define{{.*}} [2 x double] @{{.*HandleDoubles.*}}
HandleDoubles(struct Doubles x)81 LINKAGE struct Doubles HandleDoubles(struct Doubles x) { return x; }
82 
83 // AAPCS-NOT: define{{.*}} %struct.Mixed @{{.*HandleMixed.*}}
84 // PPC: define{{.*}} { i64, i64 } @{{.*HandleMixed.*}}
HandleMixed(struct Mixed x)85 LINKAGE struct Mixed HandleMixed(struct Mixed x) { return x; }
86 
87 // AAPCS: define{{.*}} %struct.FloatsBF @{{.*HandleFloatsBF.*}}
88 // PPC-C-NOT: define{{.*}} [2 x float] @{{.*HandleFloatsBF.*}}
89 // PPC-CXX: define{{.*}} [2 x float] @{{.*HandleFloatsBF.*}}
HandleFloatsBF(struct FloatsBF x)90 LINKAGE struct FloatsBF HandleFloatsBF(struct FloatsBF x) { return x; }
91 
92 // AAPCS: define{{.*}} %struct.DoublesBF @{{.*HandleDoublesBF.*}}
93 // PPC-C-NOT: define{{.*}} [2 x double] @{{.*HandleDoublesBF.*}}
94 // PPC-CXX: define{{.*}} [2 x double] @{{.*HandleDoublesBF.*}}
HandleDoublesBF(struct DoublesBF x)95 LINKAGE struct DoublesBF HandleDoublesBF(struct DoublesBF x) { return x; }
96