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

Reply via email to