| // REQUIRES: arm-registered-target,aarch64-registered-target,powerpc-registered-target |
| // RUN: %clang_cc1 -triple thumbv7-none-none -mfloat-abi hard -x c -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS |
| // RUN: %clang_cc1 -triple thumbv7-none-none -mfloat-abi hard -x c++ -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS |
| // RUN: %clang_cc1 -triple thumbv7-none-none -mfloat-abi hard -x c++ -DEXTERN_C -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS |
| // RUN: %clang_cc1 -triple aarch64-none-none -mfloat-abi hard -x c -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS |
| // RUN: %clang_cc1 -triple aarch64-none-none -mfloat-abi hard -x c++ -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS |
| // RUN: %clang_cc1 -triple aarch64-none-none -mfloat-abi hard -x c++ -DEXTERN_C -emit-llvm -o - %s | FileCheck %s --check-prefix=AAPCS |
| // 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 |
| // 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 |
| // 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 |
| |
| // The aim here is to test whether each of these structure types is |
| // regarded as a homogeneous aggregate of a single kind of |
| // floating-point item, because in all of these ABIs, that changes the |
| // calling convention. |
| // |
| // We expect that 'Floats' and 'Doubles' are homogeneous, and 'Mixed' |
| // is not. But the next two structures, with separating zero-size |
| // bitfields, are more interesting. |
| // |
| // For the Arm architecture, AAPCS says that the homogeneity rule is |
| // applied _after_ data layout is completed, so that it's unaffected |
| // by anything that was completely discarded during data layout. So we |
| // expect that FloatsBF and DoublesBF still count as homogeneous. |
| // |
| // But on PowerPC, it depends on whether the source language is C or |
| // C++, because that's consistent with the decisions gcc makes. |
| |
| struct Floats { |
| float a; |
| float b; |
| }; |
| |
| struct Doubles { |
| double a; |
| double b; |
| }; |
| |
| struct Mixed { |
| double a; |
| float b; |
| }; |
| |
| struct FloatsBF { |
| float a; |
| int : 0; |
| float b; |
| }; |
| |
| struct DoublesBF { |
| double a; |
| int : 0; |
| double b; |
| }; |
| |
| // In C++ mode, we test both with and without extern "C", to ensure |
| // that doesn't make a difference. |
| #ifdef EXTERN_C |
| #define LINKAGE extern "C" |
| #else |
| #define LINKAGE |
| #endif |
| |
| // For Arm backends, the IR emitted for the homogeneous-aggregate |
| // return convention uses the actual structure type, so that |
| // HandleFloats returns a %struct.Floats, and so on. To check that |
| // 'Mixed' is not treated as homogeneous, it's enough to check that |
| // its return type is _not_ %struct.Mixed. (The fallback handling |
| // varies between AArch32 and AArch64.) |
| // |
| // For PowerPC, homogeneous structure types are lowered to an IR array |
| // types like [2 x float], and the non-homogeneous Mixed is lowered to |
| // a pair of i64. |
| |
| // AAPCS: define{{.*}} %struct.Floats @{{.*HandleFloats.*}} |
| // PPC: define{{.*}} [2 x float] @{{.*HandleFloats.*}} |
| LINKAGE struct Floats HandleFloats(struct Floats x) { return x; } |
| |
| // AAPCS: define{{.*}} %struct.Doubles @{{.*HandleDoubles.*}} |
| // PPC: define{{.*}} [2 x double] @{{.*HandleDoubles.*}} |
| LINKAGE struct Doubles HandleDoubles(struct Doubles x) { return x; } |
| |
| // AAPCS-NOT: define{{.*}} %struct.Mixed @{{.*HandleMixed.*}} |
| // PPC: define{{.*}} { i64, i64 } @{{.*HandleMixed.*}} |
| LINKAGE struct Mixed HandleMixed(struct Mixed x) { return x; } |
| |
| // AAPCS: define{{.*}} %struct.FloatsBF @{{.*HandleFloatsBF.*}} |
| // PPC-C-NOT: define{{.*}} [2 x float] @{{.*HandleFloatsBF.*}} |
| // PPC-CXX: define{{.*}} [2 x float] @{{.*HandleFloatsBF.*}} |
| LINKAGE struct FloatsBF HandleFloatsBF(struct FloatsBF x) { return x; } |
| |
| // AAPCS: define{{.*}} %struct.DoublesBF @{{.*HandleDoublesBF.*}} |
| // PPC-C-NOT: define{{.*}} [2 x double] @{{.*HandleDoublesBF.*}} |
| // PPC-CXX: define{{.*}} [2 x double] @{{.*HandleDoublesBF.*}} |
| LINKAGE struct DoublesBF HandleDoublesBF(struct DoublesBF x) { return x; } |