Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and mallo...
[llvm-project.git] / clang / test / CodeGen / AArch64 / soft-float-abi-errors.c
blob6961ee4b88886f085ca85d30f49bdc56300ea115
1 // REQUIRES: aarch64-registered-target
3 // RUN: %clang_cc1 -triple aarch64 -target-feature +fp-armv8 -S -o /dev/null -target-abi aapcs -verify=fp-hard %s
4 // RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -S -o /dev/null -target-abi aapcs-soft -verify=nofp-soft %s
5 // RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -S -o /dev/null -target-abi aapcs -verify=nofp-hard %s
6 // RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -o /dev/null -target-abi aapcs -O1 -verify=nofp-hard,nofp-hard-opt -emit-llvm %s
7 // No run line needed for soft-float ABI with an FPU because that is rejected by the driver
9 // With the hard-float ABI and a target with an FPU, FP arguments are passed in
10 // FP registers, no diagnostics needed.
11 // fp-hard-no-diagnostics
13 // With the soft-float ABI, FP arguments are passed in integer registers, no
14 // diagnostics needed.
15 // nofp-soft-no-diagnostics
17 // With the hard-float ABI but no FPU, FP arguments cannot be passed in an
18 // ABI-compatible way, so we report errors for these cases:
20 struct HFA {
21 float x, y;
24 struct non_HFA {
25 float x;
26 int y;
29 // Floating-point arguments are returns are rejected
30 void 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}}
34 void test_float_arg(float a) {}
35 // nofp-hard-error@-1 {{'a' requires 'float' type support, but ABI 'aapcs' does not support it}}
36 float 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}}
38 void test_double_arg(double a) {}
39 // nofp-hard-error@-1 {{'a' requires 'double' type support, but ABI 'aapcs' does not support it}}
40 double 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}}
42 void 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}}
44 long 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}}
47 // HFAs would be passed in floating-point registers, so are rejected.
48 void test_hfa_arg(struct HFA a) {}
49 // nofp-hard-error@-1 {{'a' requires 'struct HFA' type support, but ABI 'aapcs' does not support it}}
50 struct 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}}
53 // Note: vector types cannot be created at all for targets without an FPU, so
54 // it is not possible to create a function which passes/returns them when using
55 // either the default or soft-float ABI. This is tested elsewhere.
57 // This struct contains a floating-point type, but is not an HFA, so can be
58 // passed/returned without affecting the ABI.
59 struct non_HFA test_non_hfa_ret(void) { return (struct non_HFA){}; }
60 void test_non_hfa_arg(struct non_HFA a) {}
62 // This inline function does not get code-generated because there is no use of
63 // it in this file, so we we don't emit an error for it, matching GCC's
64 // behaviour.
65 inline void test_float_arg_inline(float a) {}
67 // This inline function is used, so we emit the error if we generate code for
68 // it. The code isn't generated at -O0, so no error is emitted there.
69 inline 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}}
71 void 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}}
74 // The always_inline attribute causes an inline function to always be
75 // code-genned, even at -O0, so we always emit the error.
76 __attribute((always_inline))
77 inline 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}}
79 void 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}}
82 // Floating-point expressions, global variables and local variables do not
83 // affect the ABI, so are allowed. GCC does reject some uses of floating point
84 // types like this, but it does so after optimisation, which we can't
85 // accurately match in clang.
86 int test_expr_float(int a) { return a + 1.0f; }
87 int test_expr_double(int a) { return a + 1.0; }
89 float global_float = 2.0f * 3.5f;
90 float global_double = 2.0 * 3.5;
92 int test_var_float(int a) {
93 float f = a;
94 f *= 6.0;
95 return (int)f;
97 int test_var_double(int a) {
98 double d = a;
99 d *= 6.0;
100 return (int)d;
103 extern void extern_float_arg(float);
104 extern float extern_float_ret(void);
105 void 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}}
107 void 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}}
110 // Definitions of variadic functions, and calls to them which only use integer
111 // argument registers, are both fine.
112 void variadic(int, ...);
113 void call_variadic_int() { variadic(0, 1); }
115 // Calls to variadic functions with floating-point arguments are an error,
116 // since this would require floating-point registers.
117 void call_variadic_double() { variadic(0, 1.0); }
118 // nofp-hard-error@-1 {{'variadic' requires 'double' type support, but ABI 'aapcs' does not support it}}
120 // Calls through function pointers are also diagnosed.
121 void (*fptr)(float);
122 void call_indirect() { fptr(1.0f); }
123 // nofp-hard-error@-1 {{'call_indirect' requires 'float' type support, but ABI 'aapcs' does not support it}}