diff mbox series

[4/6] aarch64: Port NEON square-root intrinsics to pragma-based framework

Message ID 20260902083828.45767-5-dhruvc@nvidia.com
State New
Headers show
Series aarch64: Port NEON intrinsics to pragma-based framework using IFNs | expand

Commit Message

Dhruv Chawla Sept. 2, 2026, 8:38 a.m. UTC
From: Dhruv Chawla <dhruvc@nvidia.com>

Port the vsqrt set of intrinsics to the pragma-based framework.

The vsqrt_f64 intrinsic is not ported here as it cannot be directly
lowered from an IFN through an existing instruction pattern. This is
because the pattern does not iterate through the mode (V1DF) required to
lower it (it uses the VHSDF iterator).

Bootstrapped and regtested on aarch64-linux-gnu.

Signed-off-by: Dhruv Chawla <dhruvc@nvidia.com>

gcc/ChangeLog:

	* config/aarch64/aarch64-neon-builtins-base.cc (vsqrt, vsqrtq):
	New function bases.
	* config/aarch64/aarch64-neon-builtins-base.def (vsqrt, vsqrtq):
	New function groups.
	* config/aarch64/arm_neon.h (vsqrt_f32, vsqrtq_f32, vsqrtq_f64,
	vsqrt_f16, vsqrtq_f16): Delete functions.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/neon/vsqrt.c: New test.
---
 .../aarch64/aarch64-neon-builtins-base.cc     |  4 ++
 .../aarch64/aarch64-neon-builtins-base.def    | 12 +++++
 gcc/config/aarch64/arm_neon.h                 | 34 --------------
 gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c | 46 +++++++++++++++++++
 4 files changed, 62 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c

Comments

Kyrylo Tkachov Sept. 2, 2026, 12:09 p.m. UTC | #1
Hi Dhruv,

> On 2 Sep 2026, at 10:38, Dhruv Chawla <dhruvc@nvidia.com> wrote:
> 
> From: Dhruv Chawla <dhruvc@nvidia.com>
> 
> Port the vsqrt set of intrinsics to the pragma-based framework.
> 
> The vsqrt_f64 intrinsic is not ported here as it cannot be directly
> lowered from an IFN through an existing instruction pattern. This is
> because the pattern does not iterate through the mode (V1DF) required to
> lower it (it uses the VHSDF iterator).
> 
> Bootstrapped and regtested on aarch64-linux-gnu.
> 
> Signed-off-by: Dhruv Chawla <dhruvc@nvidia.com>
> 
> gcc/ChangeLog:
> 
> * config/aarch64/aarch64-neon-builtins-base.cc (vsqrt, vsqrtq):
> New function bases.
> * config/aarch64/aarch64-neon-builtins-base.def (vsqrt, vsqrtq):
> New function groups.
> * config/aarch64/arm_neon.h (vsqrt_f32, vsqrtq_f32, vsqrtq_f64,
> vsqrt_f16, vsqrtq_f16): Delete functions.
> 
> gcc/testsuite/ChangeLog:
> 
> * gcc.target/aarch64/neon/vsqrt.c: New test.
> ---
> .../aarch64/aarch64-neon-builtins-base.cc     |  4 ++
> .../aarch64/aarch64-neon-builtins-base.def    | 12 +++++
> gcc/config/aarch64/arm_neon.h                 | 34 --------------
> gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c | 46 +++++++++++++++++++
> 4 files changed, 62 insertions(+), 34 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c
> 
> diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> index 39f8892e35f..ca4ace4a020 100644
> --- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> @@ -785,6 +785,10 @@ NEON_FUNCTION (vhaddq,  gimple_ifn, (IFN_AVG_FLOOR))
> NEON_FUNCTION (vrhadd,  gimple_ifn, (IFN_AVG_CEIL))
> NEON_FUNCTION (vrhaddq, gimple_ifn, (IFN_AVG_CEIL))
> 
> +// Square root
> +NEON_FUNCTION (vsqrt,  gimple_ifn, (IFN_SQRT))
> +NEON_FUNCTION (vsqrtq, gimple_ifn, (IFN_SQRT))
> +

I’m worried about this. Won’t this expand to the approximate fsqrte+fsqrts sequences under -ffast-math?
Thanks,
Kyrill

> // Bitwise operations
> NEON_FUNCTION (vand,   gimple_expr,    (BIT_AND_EXPR))
> NEON_FUNCTION (vandq,  gimple_expr,    (BIT_AND_EXPR))
> diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def b/gcc/config/aarch64/aarch64-neon-builtins-base.def
> index ddb12c497bb..98efa204e4a 100644
> --- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
> +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
> @@ -122,6 +122,18 @@ DEF_NEON_FUNCTION (vrhadd,  bhs_integer, ("D0,D0,D0"))
> DEF_NEON_FUNCTION (vrhaddq, bhs_integer, ("Q0,Q0,Q0"))
> #undef REQUIRED_EXTENSIONS
> 
> +// Square root
> +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
> +DEF_NEON_FUNCTION (vsqrt,  s_float,  ("D0,D0"))
> +DEF_NEON_FUNCTION (vsqrtq, sd_float, ("Q0,Q0"))
> +#undef REQUIRED_EXTENSIONS
> +
> +// Square root (FP16)
> +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD | AARCH64_FL_F16)
> +DEF_NEON_FUNCTION (vsqrt,  h_float, ("D0,D0"))
> +DEF_NEON_FUNCTION (vsqrtq, h_float, ("Q0,Q0"))
> +#undef REQUIRED_EXTENSIONS
> +
> // Bitwise operations
> #define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
> DEF_NEON_FUNCTION (vand,   all_integer, ("D0,D0,D0"))
> diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
> index d23b59504f4..68f92f76de0 100644
> --- a/gcc/config/aarch64/arm_neon.h
> +++ b/gcc/config/aarch64/arm_neon.h
> @@ -16711,19 +16711,6 @@ vsqaddd_u64 (uint64_t __a, int64_t __b)
> }
> 
> /* vsqrt */
> -__extension__ extern __inline float32x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vsqrt_f32 (float32x2_t __a)
> -{
> -  return __builtin_aarch64_sqrtv2sf (__a);
> -}
> -
> -__extension__ extern __inline float32x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vsqrtq_f32 (float32x4_t __a)
> -{
> -  return __builtin_aarch64_sqrtv4sf (__a);
> -}
> 
> __extension__ extern __inline float64x1_t
> __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> @@ -16732,13 +16719,6 @@ vsqrt_f64 (float64x1_t __a)
>   return (float64x1_t) { __builtin_aarch64_sqrtdf (__a[0]) };
> }
> 
> -__extension__ extern __inline float64x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vsqrtq_f64 (float64x2_t __a)
> -{
> -  return __builtin_aarch64_sqrtv2df (__a);
> -}
> -
> /* vsra */
> 
> __extension__ extern __inline int8x8_t
> @@ -19318,20 +19298,6 @@ vrsqrteq_f16 (float16x8_t __a)
>   return __builtin_aarch64_rsqrtev8hf (__a);
> }
> 
> -__extension__ extern __inline float16x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vsqrt_f16 (float16x4_t __a)
> -{
> -  return __builtin_aarch64_sqrtv4hf (__a);
> -}
> -
> -__extension__ extern __inline float16x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vsqrtq_f16 (float16x8_t __a)
> -{
> -  return __builtin_aarch64_sqrtv8hf (__a);
> -}
> -
> /* ARMv8.2-A FP16 two operands vector intrinsics.  */
> 
> __extension__ extern __inline float16x4_t
> diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c b/gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c
> new file mode 100644
> index 00000000000..3b623f3ae56
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c
> @@ -0,0 +1,46 @@
> +/* { dg-do compile } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +#include "arm_neon_test.h"
> +
> +/*
> +** test_vsqrt_f16:
> +** fsqrt v0.4h, v0.4h
> +** ret
> +*/
> +TEST_UNIFORM_UNARY (vsqrt_f16, float16x4_t)
> +
> +/*
> +** test_vsqrt_f32:
> +** fsqrt v0.2s, v0.2s
> +** ret
> +*/
> +TEST_UNIFORM_UNARY (vsqrt_f32, float32x2_t)
> +
> +/*
> +** test_vsqrt_f64:
> +** fsqrt d0, d0
> +** ret
> +*/
> +TEST_UNIFORM_UNARY (vsqrt_f64, float64x1_t)
> +
> +/*
> +** test_vsqrtq_f16:
> +** fsqrt v0.8h, v0.8h
> +** ret
> +*/
> +TEST_UNIFORM_UNARY (vsqrtq_f16, float16x8_t)
> +
> +/*
> +** test_vsqrtq_f32:
> +** fsqrt v0.4s, v0.4s
> +** ret
> +*/
> +TEST_UNIFORM_UNARY (vsqrtq_f32, float32x4_t)
> +
> +/*
> +** test_vsqrtq_f64:
> +** fsqrt v0.2d, v0.2d
> +** ret
> +*/
> +TEST_UNIFORM_UNARY (vsqrtq_f64, float64x2_t)
> -- 
> 2.43.0
>
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
index 39f8892e35f..ca4ace4a020 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
@@ -785,6 +785,10 @@  NEON_FUNCTION (vhaddq,  gimple_ifn, (IFN_AVG_FLOOR))
 NEON_FUNCTION (vrhadd,  gimple_ifn, (IFN_AVG_CEIL))
 NEON_FUNCTION (vrhaddq, gimple_ifn, (IFN_AVG_CEIL))
 
+// Square root
+NEON_FUNCTION (vsqrt,  gimple_ifn, (IFN_SQRT))
+NEON_FUNCTION (vsqrtq, gimple_ifn, (IFN_SQRT))
+
 // Bitwise operations
 NEON_FUNCTION (vand,   gimple_expr,    (BIT_AND_EXPR))
 NEON_FUNCTION (vandq,  gimple_expr,    (BIT_AND_EXPR))
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def b/gcc/config/aarch64/aarch64-neon-builtins-base.def
index ddb12c497bb..98efa204e4a 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
@@ -122,6 +122,18 @@  DEF_NEON_FUNCTION (vrhadd,  bhs_integer, ("D0,D0,D0"))
 DEF_NEON_FUNCTION (vrhaddq, bhs_integer, ("Q0,Q0,Q0"))
 #undef REQUIRED_EXTENSIONS
 
+// Square root
+#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
+DEF_NEON_FUNCTION (vsqrt,  s_float,  ("D0,D0"))
+DEF_NEON_FUNCTION (vsqrtq, sd_float, ("Q0,Q0"))
+#undef REQUIRED_EXTENSIONS
+
+// Square root (FP16)
+#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD | AARCH64_FL_F16)
+DEF_NEON_FUNCTION (vsqrt,  h_float, ("D0,D0"))
+DEF_NEON_FUNCTION (vsqrtq, h_float, ("Q0,Q0"))
+#undef REQUIRED_EXTENSIONS
+
 // Bitwise operations
 #define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
 DEF_NEON_FUNCTION (vand,   all_integer, ("D0,D0,D0"))
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index d23b59504f4..68f92f76de0 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -16711,19 +16711,6 @@  vsqaddd_u64 (uint64_t __a, int64_t __b)
 }
 
 /* vsqrt */
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vsqrt_f32 (float32x2_t __a)
-{
-  return __builtin_aarch64_sqrtv2sf (__a);
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vsqrtq_f32 (float32x4_t __a)
-{
-  return __builtin_aarch64_sqrtv4sf (__a);
-}
 
 __extension__ extern __inline float64x1_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
@@ -16732,13 +16719,6 @@  vsqrt_f64 (float64x1_t __a)
   return (float64x1_t) { __builtin_aarch64_sqrtdf (__a[0]) };
 }
 
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vsqrtq_f64 (float64x2_t __a)
-{
-  return __builtin_aarch64_sqrtv2df (__a);
-}
-
 /* vsra */
 
 __extension__ extern __inline int8x8_t
@@ -19318,20 +19298,6 @@  vrsqrteq_f16 (float16x8_t __a)
   return __builtin_aarch64_rsqrtev8hf (__a);
 }
 
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vsqrt_f16 (float16x4_t __a)
-{
-  return __builtin_aarch64_sqrtv4hf (__a);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vsqrtq_f16 (float16x8_t __a)
-{
-  return __builtin_aarch64_sqrtv8hf (__a);
-}
-
 /* ARMv8.2-A FP16 two operands vector intrinsics.  */
 
 __extension__ extern __inline float16x4_t
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c b/gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c
new file mode 100644
index 00000000000..3b623f3ae56
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vsqrt.c
@@ -0,0 +1,46 @@ 
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vsqrt_f16:
+** fsqrt	v0.4h, v0.4h
+** ret
+*/
+TEST_UNIFORM_UNARY (vsqrt_f16, float16x4_t)
+
+/*
+** test_vsqrt_f32:
+** fsqrt	v0.2s, v0.2s
+** ret
+*/
+TEST_UNIFORM_UNARY (vsqrt_f32, float32x2_t)
+
+/*
+** test_vsqrt_f64:
+** fsqrt	d0, d0
+** ret
+*/
+TEST_UNIFORM_UNARY (vsqrt_f64, float64x1_t)
+
+/*
+** test_vsqrtq_f16:
+** fsqrt	v0.8h, v0.8h
+** ret
+*/
+TEST_UNIFORM_UNARY (vsqrtq_f16, float16x8_t)
+
+/*
+** test_vsqrtq_f32:
+** fsqrt	v0.4s, v0.4s
+** ret
+*/
+TEST_UNIFORM_UNARY (vsqrtq_f32, float32x4_t)
+
+/*
+** test_vsqrtq_f64:
+** fsqrt	v0.2d, v0.2d
+** ret
+*/
+TEST_UNIFORM_UNARY (vsqrtq_f64, float64x2_t)