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