fortran: Allow vector math functions only with fast-math [PR 118955]

Message ID PAWPR08MB89820EFAEA3331B86B9888D58317A@PAWPR08MB8982.eurprd08.prod.outlook.com
State Committed
Commit 66a2e7137049482ac317a5af8d64f43c315f87a6
Headers
Series fortran: Allow vector math functions only with fast-math [PR 118955] |

Commit Message

Wilco Dijkstra Sept. 17, 2025, 5:19 p.m. UTC
  Vector math functions are currently always enabled in Fortran.  This is
incorrect since vector math functions are designed to be Ofast only.
Add a new 'fastmath' option which only accepts vector functions if fast-math
is enabled:

!GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')

Passes regress.

gcc:
	PR fortran/118955
	* fortran/decl.cc (gfc_match_gcc_builtin): Add 'fastmath' option which
	checks for fast-math before accepting a vector function.
	* fortran/gfortran.texi (!GCC$ builtin): Update documentation. 

gcc/testsuite:
	PR fortran/118955
	* gfortran.dg/simd-builtins-9.f90: Add new test.	
	* gfortran.dg/simd-builtins-9.h: Likewise.

---
  

Comments

Wilco Dijkstra Jan. 13, 2026, 1:17 p.m. UTC | #1
ping
  
Wilco Dijkstra Jan. 13, 2026, 1:27 p.m. UTC | #2
Adding Fortran list too

ping
  
Harald Anlauf Jan. 13, 2026, 8:29 p.m. UTC | #3
Hi Wilco,

Am 13.01.26 um 2:27 PM schrieb Wilco Dijkstra:
> 
> Adding Fortran list too
> 
> ping

the patch does not apply cleanly here.  Can you rebase it?

Thanks,
Harald


> ________________________________________
> From: Wilco Dijkstra
> Sent: 17 September 2025 18:19
> To: GCC Patches <gcc-patches@gcc.gnu.org>
> Subject: [PATCH] fortran: Allow vector math functions only with fast-math [PR 118955]
>   
> 
> Vector math functions are currently always enabled in Fortran.  This is
> incorrect since vector math functions are designed to be Ofast only.
> Add a new 'fastmath' option which only accepts vector functions if fast-math
> is enabled:
> 
> !GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')
> 
> Passes regress.
> 
> gcc:
>          PR fortran/118955
>          * fortran/decl.cc (gfc_match_gcc_builtin): Add 'fastmath' option which
>          checks for fast-math before accepting a vector function.
>          * fortran/gfortran.texi (!GCC$ builtin): Update documentation.
> 
> gcc/testsuite:
>          PR fortran/118955
>          * gfortran.dg/simd-builtins-9.f90: Add new test.
>          * gfortran.dg/simd-builtins-9.h: Likewise.
> 
> ---
> 
> diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
> index 9fe697cd5498467df2600fe878956e8050a28adb..04ed9075491d3ec2c9d7fb75bced34f9ffb9f577 100644
> --- a/gcc/fortran/decl.cc
> +++ b/gcc/fortran/decl.cc
> @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "parse.h"
>   #include "constructor.h"
>   #include "target.h"
> +#include "flags.h"
>   
>   /* Macros to access allocate memory for gfc_data_variable,
>      gfc_data_value and gfc_data.  */
> @@ -12562,9 +12563,17 @@ gfc_match_gcc_builtin (void)
>   
>     if (gfc_match (" if ( '%n' ) ", target) == MATCH_YES)
>       {
> -      const char *abi = targetm.get_multilib_abi_name ();
> -      if (abi == NULL || strcmp (abi, target) != 0)
> -       return MATCH_YES;
> +      if (strcmp (target, "fastmath") == 0)
> +       {
> +         if (!fast_math_flags_set_p (&global_options))
> +           return MATCH_YES;
> +       }
> +      else
> +       {
> +         const char *abi = targetm.get_multilib_abi_name ();
> +         if (abi == NULL || strcmp (abi, target) != 0)
> +           return MATCH_YES;
> +       }
>       }
>   
>     if (gfc_vectorized_builtins == NULL)
> diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
> index 841f6135066043935ca31496e910c69908c0c53e..e76c37f8123d0b5885730f01928d821606d42752 100644
> --- a/gcc/fortran/gfortran.texi
> +++ b/gcc/fortran/gfortran.texi
> @@ -3470,6 +3470,13 @@ for the built-in that should be vectorized.  Example usage:
>   !GCC$ builtin (sinf) attributes simd (notinbranch) if('x86_64')
>   @end smallexample
>   
> +The special target @code{'fastmath'} is used to specify the vector
> +implementation is only valid if fast-math is enabled:
> +
> +@smallexample
> +!GCC$ builtin (exp) attributes simd (notinbranch) if('fastmath')
> +@end smallexample
> +
>   The purpose of the directive is to provide an API among the GCC compiler and
>   the GNU C Library which would define vector implementations of math routines.
>   
> diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
> new file mode 100644
> index 0000000000000000000000000000000000000000..02944e578533afccc90768516cafb473f098f19d
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
> @@ -0,0 +1,16 @@
> +! { dg-do compile { target { aarch64*-*-linux* } } }
> +! { dg-additional-options "-nostdinc -O3 -fpre-include=simd-builtins-9.h -fdump-tree-optimized" }
> +
> +program test_overloaded_intrinsic
> +  real(8) :: x8(3200), y8(3200)
> +
> +  y8 = sin(x8)
> +  print *, y8
> +
> +  x8 = cos(y8)
> +  print *, x8
> +end
> +
> +! { dg-final { scan-tree-dump-not "sin.simdclone" "optimized" } } */
> +
> +! { dg-final { scan-tree-dump "cos.simdclone" "optimized" } } */
> diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.h b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..3ca3ea8062c9d1c99ccabc9dd5466befd6e6d4f6
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
> @@ -0,0 +1,2 @@
> +!GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')
> +!GCC$ builtin (cos) attributes simd (notinbranch)
  
Wilco Dijkstra Jan. 14, 2026, 6:17 p.m. UTC | #4
Hi Harald,

> the patch does not apply cleanly here.  Can you rebase it?

Sure, see below:

Cheers,
Wilco


v2: Rebased to current trunk

Vector math functions are currently always enabled in Fortran.  This is
incorrect since vector math functions are designed to be Ofast only.
Add a new 'fastmath' option which only accepts vector functions if fast-math
is enabled:

!GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')

Passes regress.

gcc:
	PR fortran/118955
	* fortran/decl.cc (gfc_match_gcc_builtin): Add 'fastmath' option which
	checks for fast-math before accepting a vector function.
	* fortran/gfortran.texi (!GCC$ builtin): Update documentation. 

gcc/testsuite:
	PR fortran/118955
	* gfortran.dg/simd-builtins-9.f90: Add new test.
	* gfortran.dg/simd-builtins-9.h: Likewise.

---

diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 3d0410501b65dd4328815cdedda8c0e24cf2e00f..5348dc1bcacdd1173b37c696f053a2b8f3c66188 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "parse.h"
 #include "constructor.h"
 #include "target.h"
+#include "flags.h"
 
 /* Macros to access allocate memory for gfc_data_variable,
    gfc_data_value and gfc_data.  */
@@ -12803,9 +12804,17 @@ gfc_match_gcc_builtin (void)
 
   if (gfc_match (" if ( '%n' ) ", target) == MATCH_YES)
     {
-      const char *abi = targetm.get_multilib_abi_name ();
-      if (abi == NULL || strcmp (abi, target) != 0)
-	return MATCH_YES;
+      if (strcmp (target, "fastmath") == 0)
+	{
+	  if (!fast_math_flags_set_p (&global_options))
+	    return MATCH_YES;
+	}
+      else
+	{
+	  const char *abi = targetm.get_multilib_abi_name ();
+	  if (abi == NULL || strcmp (abi, target) != 0)
+	    return MATCH_YES;
+	}
     }
 
   if (gfc_vectorized_builtins == NULL)
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index c4f39acf6bc31398d010a4165e31b871b39aab20..a930cc1dc9c04348d9ef284789720a79055ca702 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -3454,6 +3454,13 @@ for the built-in that should be vectorized.  Example usage:
 !GCC$ builtin (sinf) attributes simd (notinbranch) if('x86_64')
 @end smallexample
 
+The special target @code{'fastmath'} is used to specify the vector
+implementation is only valid if fast-math is enabled:
+
+@smallexample
+!GCC$ builtin (exp) attributes simd (notinbranch) if('fastmath')
+@end smallexample
+
 The purpose of the directive is to provide an API among the GCC compiler and
 the GNU C Library which would define vector implementations of math routines.
 
diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
new file mode 100644
index 0000000000000000000000000000000000000000..02944e578533afccc90768516cafb473f098f19d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
@@ -0,0 +1,16 @@
+! { dg-do compile { target { aarch64*-*-linux* } } }
+! { dg-additional-options "-nostdinc -O3 -fpre-include=simd-builtins-9.h -fdump-tree-optimized" }
+
+program test_overloaded_intrinsic
+  real(8) :: x8(3200), y8(3200)
+
+  y8 = sin(x8)
+  print *, y8
+
+  x8 = cos(y8)
+  print *, x8
+end
+
+! { dg-final { scan-tree-dump-not "sin.simdclone" "optimized" } } */
+
+! { dg-final { scan-tree-dump "cos.simdclone" "optimized" } } */
diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.h b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ca3ea8062c9d1c99ccabc9dd5466befd6e6d4f6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
@@ -0,0 +1,2 @@
+!GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')
+!GCC$ builtin (cos) attributes simd (notinbranch)
  
Harald Anlauf Jan. 14, 2026, 8:22 p.m. UTC | #5
Hi Wilco,

Am 14.01.26 um 7:17 PM schrieb Wilco Dijkstra:
> Hi Harald,
> 
>> the patch does not apply cleanly here.  Can you rebase it?
> 
> Sure, see below:
> 
> Cheers,
> Wilco
> 
> 
> v2: Rebased to current trunk

thanks, this works here.

The patch looks good to me.

Regarding your testcase, which is target-specific: you restrict
it to aarch64, but it should in principle work on x64_64 too,
and maybe on several other supported platforms.
I verified that manually, as it is reported as unsupported
when running the testsuite on x86_64-pc-linux-gnu.

So if you - or someone else - find a better choice here, it is
pre-approved.

Thanks for the patch!

Harald

> Vector math functions are currently always enabled in Fortran.  This is
> incorrect since vector math functions are designed to be Ofast only.
> Add a new 'fastmath' option which only accepts vector functions if fast-math
> is enabled:
> 
> !GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')
> 
> Passes regress.
> 
> gcc:
> 	PR fortran/118955
> 	* fortran/decl.cc (gfc_match_gcc_builtin): Add 'fastmath' option which
> 	checks for fast-math before accepting a vector function.
> 	* fortran/gfortran.texi (!GCC$ builtin): Update documentation.
> 
> gcc/testsuite:
> 	PR fortran/118955
> 	* gfortran.dg/simd-builtins-9.f90: Add new test.
> 	* gfortran.dg/simd-builtins-9.h: Likewise.
> 
> ---
> 
> diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
> index 3d0410501b65dd4328815cdedda8c0e24cf2e00f..5348dc1bcacdd1173b37c696f053a2b8f3c66188 100644
> --- a/gcc/fortran/decl.cc
> +++ b/gcc/fortran/decl.cc
> @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "parse.h"
>   #include "constructor.h"
>   #include "target.h"
> +#include "flags.h"
>   
>   /* Macros to access allocate memory for gfc_data_variable,
>      gfc_data_value and gfc_data.  */
> @@ -12803,9 +12804,17 @@ gfc_match_gcc_builtin (void)
>   
>     if (gfc_match (" if ( '%n' ) ", target) == MATCH_YES)
>       {
> -      const char *abi = targetm.get_multilib_abi_name ();
> -      if (abi == NULL || strcmp (abi, target) != 0)
> -	return MATCH_YES;
> +      if (strcmp (target, "fastmath") == 0)
> +	{
> +	  if (!fast_math_flags_set_p (&global_options))
> +	    return MATCH_YES;
> +	}
> +      else
> +	{
> +	  const char *abi = targetm.get_multilib_abi_name ();
> +	  if (abi == NULL || strcmp (abi, target) != 0)
> +	    return MATCH_YES;
> +	}
>       }
>   
>     if (gfc_vectorized_builtins == NULL)
> diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
> index c4f39acf6bc31398d010a4165e31b871b39aab20..a930cc1dc9c04348d9ef284789720a79055ca702 100644
> --- a/gcc/fortran/gfortran.texi
> +++ b/gcc/fortran/gfortran.texi
> @@ -3454,6 +3454,13 @@ for the built-in that should be vectorized.  Example usage:
>   !GCC$ builtin (sinf) attributes simd (notinbranch) if('x86_64')
>   @end smallexample
>   
> +The special target @code{'fastmath'} is used to specify the vector
> +implementation is only valid if fast-math is enabled:
> +
> +@smallexample
> +!GCC$ builtin (exp) attributes simd (notinbranch) if('fastmath')
> +@end smallexample
> +
>   The purpose of the directive is to provide an API among the GCC compiler and
>   the GNU C Library which would define vector implementations of math routines.
>   
> diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
> new file mode 100644
> index 0000000000000000000000000000000000000000..02944e578533afccc90768516cafb473f098f19d
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
> @@ -0,0 +1,16 @@
> +! { dg-do compile { target { aarch64*-*-linux* } } }
> +! { dg-additional-options "-nostdinc -O3 -fpre-include=simd-builtins-9.h -fdump-tree-optimized" }
> +
> +program test_overloaded_intrinsic
> +  real(8) :: x8(3200), y8(3200)
> +
> +  y8 = sin(x8)
> +  print *, y8
> +
> +  x8 = cos(y8)
> +  print *, x8
> +end
> +
> +! { dg-final { scan-tree-dump-not "sin.simdclone" "optimized" } } */
> +
> +! { dg-final { scan-tree-dump "cos.simdclone" "optimized" } } */
> diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.h b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..3ca3ea8062c9d1c99ccabc9dd5466befd6e6d4f6
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
> @@ -0,0 +1,2 @@
> +!GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')
> +!GCC$ builtin (cos) attributes simd (notinbranch)
> 
>
  

Patch

diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 9fe697cd5498467df2600fe878956e8050a28adb..04ed9075491d3ec2c9d7fb75bced34f9ffb9f577 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -29,6 +29,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "parse.h"
 #include "constructor.h"
 #include "target.h"
+#include "flags.h"
 
 /* Macros to access allocate memory for gfc_data_variable,
    gfc_data_value and gfc_data.  */
@@ -12562,9 +12563,17 @@  gfc_match_gcc_builtin (void)
 
   if (gfc_match (" if ( '%n' ) ", target) == MATCH_YES)
     {
-      const char *abi = targetm.get_multilib_abi_name ();
-      if (abi == NULL || strcmp (abi, target) != 0)
-	return MATCH_YES;
+      if (strcmp (target, "fastmath") == 0)
+	{
+	  if (!fast_math_flags_set_p (&global_options))
+	    return MATCH_YES;
+	}
+      else
+	{
+	  const char *abi = targetm.get_multilib_abi_name ();
+	  if (abi == NULL || strcmp (abi, target) != 0)
+	    return MATCH_YES;
+	}
     }
 
   if (gfc_vectorized_builtins == NULL)
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 841f6135066043935ca31496e910c69908c0c53e..e76c37f8123d0b5885730f01928d821606d42752 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -3470,6 +3470,13 @@  for the built-in that should be vectorized.  Example usage:
 !GCC$ builtin (sinf) attributes simd (notinbranch) if('x86_64')
 @end smallexample
 
+The special target @code{'fastmath'} is used to specify the vector
+implementation is only valid if fast-math is enabled:
+
+@smallexample
+!GCC$ builtin (exp) attributes simd (notinbranch) if('fastmath')
+@end smallexample
+
 The purpose of the directive is to provide an API among the GCC compiler and
 the GNU C Library which would define vector implementations of math routines.
 
diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
new file mode 100644
index 0000000000000000000000000000000000000000..02944e578533afccc90768516cafb473f098f19d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.f90
@@ -0,0 +1,16 @@ 
+! { dg-do compile { target { aarch64*-*-linux* } } }
+! { dg-additional-options "-nostdinc -O3 -fpre-include=simd-builtins-9.h -fdump-tree-optimized" }
+
+program test_overloaded_intrinsic
+  real(8) :: x8(3200), y8(3200)
+
+  y8 = sin(x8)
+  print *, y8
+
+  x8 = cos(y8)
+  print *, x8
+end
+
+! { dg-final { scan-tree-dump-not "sin.simdclone" "optimized" } } */
+
+! { dg-final { scan-tree-dump "cos.simdclone" "optimized" } } */
diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-9.h b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ca3ea8062c9d1c99ccabc9dd5466befd6e6d4f6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/simd-builtins-9.h
@@ -0,0 +1,2 @@ 
+!GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath')
+!GCC$ builtin (cos) attributes simd (notinbranch)