124 lines · c
1// REQUIRES: aarch64-registered-target2 3// RUN: %clang_cc1 -triple aarch64 -target-feature +fp-armv8 -S -o /dev/null -target-abi aapcs -verify=fp-hard %s4// RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -S -o /dev/null -target-abi aapcs-soft -verify=nofp-soft %s5// RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -S -o /dev/null -target-abi aapcs -verify=nofp-hard %s6// RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -o /dev/null -target-abi aapcs -O1 -verify=nofp-hard,nofp-hard-opt -emit-llvm %s7// No run line needed for soft-float ABI with an FPU because that is rejected by the driver8 9// With the hard-float ABI and a target with an FPU, FP arguments are passed in10// FP registers, no diagnostics needed.11// fp-hard-no-diagnostics12 13// With the soft-float ABI, FP arguments are passed in integer registers, no14// diagnostics needed.15// nofp-soft-no-diagnostics16 17// With the hard-float ABI but no FPU, FP arguments cannot be passed in an18// ABI-compatible way, so we report errors for these cases:19 20struct HFA {21 float x, y;22};23 24struct non_HFA {25 float x;26 int y;27};28 29// Floating-point arguments are returns are rejected30void test_fp16_arg(__fp16 a) {}31// nofp-hard-error@-1 {{'a' requires '__fp16' type support, but ABI 'aapcs' does not support it}}32__fp16 test_fp16_ret(void) { return 3.141; }33// nofp-hard-error@-1 {{'test_fp16_ret' requires '__fp16' type support, but ABI 'aapcs' does not support it}}34void test_float_arg(float a) {}35// nofp-hard-error@-1 {{'a' requires 'float' type support, but ABI 'aapcs' does not support it}}36float test_float_ret(void) { return 3.141f; }37// nofp-hard-error@-1 {{'test_float_ret' requires 'float' type support, but ABI 'aapcs' does not support it}}38void test_double_arg(double a) {}39// nofp-hard-error@-1 {{'a' requires 'double' type support, but ABI 'aapcs' does not support it}}40double test_double_ret(void) { return 3.141; }41// nofp-hard-error@-1 {{'test_double_ret' requires 'double' type support, but ABI 'aapcs' does not support it}}42void test_long_double_arg(long double a) {}43// nofp-hard-error@-1 {{'a' requires 'long double' type support, but ABI 'aapcs' does not support it}}44long double test_long_double_ret(void) { return 3.141L; }45// nofp-hard-error@-1 {{'test_long_double_ret' requires 'long double' type support, but ABI 'aapcs' does not support it}}46 47// HFAs would be passed in floating-point registers, so are rejected.48void test_hfa_arg(struct HFA a) {}49// nofp-hard-error@-1 {{'a' requires 'struct HFA' type support, but ABI 'aapcs' does not support it}}50struct HFA test_hfa_ret(void) { return (struct HFA){}; }51// nofp-hard-error@-1 {{'test_hfa_ret' requires 'struct HFA' type support, but ABI 'aapcs' does not support it}}52 53// Note: vector types cannot be created at all for targets without an FPU, so54// it is not possible to create a function which passes/returns them when using55// either the default or soft-float ABI. This is tested elsewhere.56 57// This struct contains a floating-point type, but is not an HFA, so can be58// passed/returned without affecting the ABI.59struct non_HFA test_non_hfa_ret(void) { return (struct non_HFA){}; }60void test_non_hfa_arg(struct non_HFA a) {}61 62// This inline function does not get code-generated because there is no use of63// it in this file, so we we don't emit an error for it, matching GCC's64// behaviour.65inline void test_float_arg_inline(float a) {}66 67// This inline function is used, so we emit the error if we generate code for68// it. The code isn't generated at -O0, so no error is emitted there.69inline void test_float_arg_inline_used(float a) {}70// nofp-hard-opt-error@-1 {{'a' requires 'float' type support, but ABI 'aapcs' does not support it}}71void use_inline() { test_float_arg_inline_used(1.0f); }72// nofp-hard-error@-1 {{'test_float_arg_inline_used' requires 'float' type support, but ABI 'aapcs' does not support it}}73 74// The always_inline attribute causes an inline function to always be75// code-genned, even at -O0, so we always emit the error.76__attribute((always_inline))77inline void test_float_arg_always_inline_used(float a) {}78// nofp-hard-error@-1 {{'a' requires 'float' type support, but ABI 'aapcs' does not support it}}79void use_always_inline() { test_float_arg_always_inline_used(1.0f); }80// nofp-hard-error@-1 {{'test_float_arg_always_inline_used' requires 'float' type support, but ABI 'aapcs' does not support it}}81 82// Floating-point expressions, global variables and local variables do not83// affect the ABI, so are allowed. GCC does reject some uses of floating point84// types like this, but it does so after optimisation, which we can't85// accurately match in clang.86int test_expr_float(int a) { return a + 1.0f; }87int test_expr_double(int a) { return a + 1.0; }88 89float global_float = 2.0f * 3.5f;90float global_double = 2.0 * 3.5;91 92int test_var_float(int a) {93 float f = a;94 f *= 6.0;95 return (int)f;96}97int test_var_double(int a) {98 double d = a;99 d *= 6.0;100 return (int)d;101}102 103extern void extern_float_arg(float);104extern float extern_float_ret(void);105void call_extern_float_arg() { extern_float_arg(1.0f); }106// nofp-hard-error@-1 {{'extern_float_arg' requires 'float' type support, but ABI 'aapcs' does not support it}}107void call_extern_float_ret() { extern_float_ret(); }108// nofp-hard-error@-1 {{'extern_float_ret' requires 'float' type support, but ABI 'aapcs' does not support it}}109 110// Definitions of variadic functions, and calls to them which only use integer111// argument registers, are both fine.112void variadic(int, ...);113void call_variadic_int() { variadic(0, 1); }114 115// Calls to variadic functions with floating-point arguments are an error,116// since this would require floating-point registers.117void call_variadic_double() { variadic(0, 1.0); }118// nofp-hard-error@-1 {{'variadic' requires 'double' type support, but ABI 'aapcs' does not support it}}119 120// Calls through function pointers are also diagnosed.121void (*fptr)(float);122void call_indirect() { fptr(1.0f); }123// nofp-hard-error@-1 {{'call_indirect' requires 'float' type support, but ABI 'aapcs' does not support it}}124