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