https://gcc.gnu.org/g:3adc17073b38eb5a29e228c05f4b35dfc4d87fee
commit r17-3982-g3adc17073b38eb5a29e228c05f4b35dfc4d87fee Author: Jack O'Donohue <[email protected]> Date: Tue Sep 8 13:10:28 2026 +0900 SH: Fix __builtin_sh_{get,set}_fpscr ICE on targets without FPU Attempting to use __builtin_sh_{get,set}_fpscr with sh-elf-gcc on targets without TARGET_FPU_ANY results in an ICE because the built-ins are enabled when TARGET_SH1 is set, but their RTL expansions require TARGET_FPU_ANY. Fixed by adjusting the TARGET_xxx check to enable/not enable the builtins. gcc/ChangeLog: * config/sh/sh.cc (sh1_builtin_p): Rename to sh_fpu_p. (sh_fpu_p): Check TARGET_FPU_ANY instead of TARGET_SH1. (bdesc): Update sh1_builtin_p to sh_fpu_p. gcc/testsuite/ChangeLog: * gcc.target/sh/getset-fpscr-1.c: New test. * gcc.target/sh/getset-fpscr-2.c: New test. * gcc.target/sh/getset-fpscr-3.c: New test. Signed-off-by: Jack O'Donohue <[email protected]> Diff: --- gcc/config/sh/sh.cc | 16 ++++++++++------ gcc/testsuite/gcc.target/sh/getset-fpscr-1.c | 11 +++++++++++ gcc/testsuite/gcc.target/sh/getset-fpscr-2.c | 9 +++++++++ gcc/testsuite/gcc.target/sh/getset-fpscr-3.c | 12 ++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc index 05b0060c0c18..880b0b9239f2 100644 --- a/gcc/config/sh/sh.cc +++ b/gcc/config/sh/sh.cc @@ -10097,6 +10097,12 @@ sh_expand_sym_label2reg (rtx reg, rtx sym, rtx lab, bool sibcall_p) struct builtin_description { + /* Tells whether the built-in can be used. + A built-in that is not enabled is not declared. This allows using + '__has_builtin' on it to check its presence. However, if not present, it + will ultimately result in a function call to an undeclared function. + The alternative would be to always declare it and throw a compiler error + during builtin expansion, as it's done on i386. */ bool (* const is_enabled) (void); const enum insn_code icode; const char *const name; @@ -10104,12 +10110,10 @@ struct builtin_description tree fndecl; }; -/* This function can be used if there are any built-ins that are not for - SHmedia. It's commented out to avoid the defined-but-unused warning. */ static bool -sh1_builtin_p (void) +sh_fpu_p (void) { - return TARGET_SH1; + return TARGET_FPU_ANY; } /* describe number and signedness of arguments; arg[0] == result @@ -10184,9 +10188,9 @@ static const char signature_args[][4] = /* nsb: takes long long arg, returns unsigned char. */ static struct builtin_description bdesc[] = { - { sh1_builtin_p, + { sh_fpu_p, CODE_FOR_sts_fpscr, "__builtin_sh_get_fpscr", SH_BLTIN_UV, 0 }, - { sh1_builtin_p, + { sh_fpu_p, CODE_FOR_set_fpscr, "__builtin_sh_set_fpscr", SH_BLTIN_VU, 0 }, }; diff --git a/gcc/testsuite/gcc.target/sh/getset-fpscr-1.c b/gcc/testsuite/gcc.target/sh/getset-fpscr-1.c new file mode 100644 index 000000000000..39d55e0d2721 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/getset-fpscr-1.c @@ -0,0 +1,11 @@ +/* Verify that no ICE occurs if target doesn't have an FPU. */ +/* { dg-do compile { target { no_fpu } } } */ +/* The default -ansi makes an implicit declaration legal and silent. */ +/* { dg-options "-Werror=implicit-function-declaration" } */ + +void +error (void) +{ + __builtin_sh_get_fpscr (); /* { dg-error "implicit declaration of function" } */ + __builtin_sh_set_fpscr (0); /* { dg-error "implicit declaration of function" } */ +} diff --git a/gcc/testsuite/gcc.target/sh/getset-fpscr-2.c b/gcc/testsuite/gcc.target/sh/getset-fpscr-2.c new file mode 100644 index 000000000000..b96fed812b29 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/getset-fpscr-2.c @@ -0,0 +1,9 @@ +/* Verify that built-ins compile correctly if floating-point is supported. */ +/* { dg-do compile { target { any_fpu } } } */ + +void +test (void) +{ + __builtin_sh_get_fpscr (); + __builtin_sh_set_fpscr (0); +} diff --git a/gcc/testsuite/gcc.target/sh/getset-fpscr-3.c b/gcc/testsuite/gcc.target/sh/getset-fpscr-3.c new file mode 100644 index 000000000000..850ca960ce8e --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/getset-fpscr-3.c @@ -0,0 +1,12 @@ +/* Verify that __has_builtin reports whether the built-ins are available. */ +/* { dg-do compile } */ +/* The default -ansi predates static_assert. */ +/* { dg-options "-std=c23" } */ + +#ifdef __SH_FPU_ANY__ +static_assert (__has_builtin (__builtin_sh_get_fpscr)); +static_assert (__has_builtin (__builtin_sh_set_fpscr)); +#else +static_assert (!__has_builtin (__builtin_sh_get_fpscr)); +static_assert (!__has_builtin (__builtin_sh_set_fpscr)); +#endif
