Port the `vabs` family of NEON intrinsics to the pragma-based framework,
and add assembly tests for every variant.
This also makes the `__builtin_aarch64_abs<mode>` builtin functions
obsolete, so they have been deleted too.
gcc/ChangeLog:
* config/aarch64/aarch64-builtins.cc
(aarch64_general_fold_builtin): Delete case to handle `abs`.
* config/aarch64/aarch64-neon-builtins-base.cc (vabsd, vabsh,
vabs, vabsq): New function bases.
* config/aarch64/aarch64-neon-builtins-base.def (vabsd): (vabs):
(vabsq): (vabsh): New function declarations.
* config/aarch64/aarch64-simd-builtins.def: Delete `abs` builtin
functions.
* config/aarch64/aarch64-simd.md
(aarch64_abs<mode><vczle><vczbe>): Replace UNSPEC_ABS with abs
expression.
(aarch64_abs_plus<mode>): Likewise.
* config/aarch64/iterators.md (UNSPEC_ABS): Delete unspec.
* config/aarch64/arm_neon.h (vabs_f32, vabs_f64, vabs_s8,
vabs_s16, vabs_s32, vabs_s64, vabsq_f32, vabsq_f64, vabsq_s8,
vabsq_s16, vabsq_s32, vabsq_s64, vabsd_s64, vabs_f16,
vabsq_f16): Delete function definitions.
* config/aarch64/arm_fp16.h (vabsh_f16): Use `__builtin_fabs`
instead of `__builtin_aarch64_abshf` now that the latter has
been deleted.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/neon/vabs.c: New test.
* gcc.target/aarch64/neon/trapping_math.c: New tests.
* gcc.target/aarch64/singleton_intrinsics_1.c: Mark `vabs_s64`
test as `xfail` because of codegen regression.
* gcc.target/aarch64/vabs_intrinsic_1.c: Fix test. The `asm
volatile` trick for disabling constant folding stopped
working. Replace with declaring variables `volatile`.
* gcc.target/aarch64/fneg-abs_1.c: Add `-fno-trapping-math`
to flags.
* gcc.target/aarch64/sve/fneg-abs_1.c: Likewise.
---
gcc/config/aarch64/aarch64-builtins.cc | 2 -
.../aarch64/aarch64-neon-builtins-base.cc | 106 ++++++++++++++++
.../aarch64/aarch64-neon-builtins-base.def | 11 ++
gcc/config/aarch64/aarch64-simd-builtins.def | 6 -
gcc/config/aarch64/aarch64-simd.md | 18 +--
gcc/config/aarch64/arm_fp16.h | 2 +-
gcc/config/aarch64/arm_neon.h | 112 -----------------
gcc/config/aarch64/iterators.md | 1 -
gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c | 2 +-
.../gcc.target/aarch64/neon/trapping_math.c | 66 ++++++++++
gcc/testsuite/gcc.target/aarch64/neon/vabs.c | 116 ++++++++++++++++++
.../aarch64/singleton_intrinsics_1.c | 2 +-
.../gcc.target/aarch64/sve/fneg-abs_1.c | 2 +-
.../gcc.target/aarch64/vabs_intrinsic_1.c | 9 +-
14 files changed, 308 insertions(+), 147 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vabs.c
diff --git a/gcc/config/aarch64/aarch64-builtins.cc
b/gcc/config/aarch64/aarch64-builtins.cc
index 8a82b131b72..ab9dec83744 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -4554,8 +4554,6 @@ aarch64_general_fold_builtin (unsigned int fcode, tree
type,
{
switch (fcode)
{
- BUILTIN_VDQF (UNOP, abs, 2, ALL)
- return fold_build1 (ABS_EXPR, type, args[0]);
VAR1 (UNOP, floatv2si, 2, ALL, v2sf)
VAR1 (UNOP, floatv4si, 2, ALL, v4sf)
VAR1 (UNOP, floatv2di, 2, ALL, v2df)
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
index 9f7cafe76a4..620dd1fb206 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
@@ -821,6 +821,111 @@ struct gimple_reinterpret : public gimple_function_base
}
};
+struct gimple_abs : public gimple_function_base
+{
+ unsigned call_properties (const function_instance &fi) const override
+ {
+ return (flag_trapping_math && fi.type_suffix (0).tclass == TYPE_float)
+ ? CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS
+ : 0;
+ }
+
+ gimple *fold (gimple_folder &f) const override
+ {
+ auto arg = gimple_call_arg (f.call, 0);
+ auto arg_type = TREE_TYPE (arg);
+
+ if (!FLOAT_TYPE_P (arg_type))
+ return gimple_build_assign (
+ f.lhs, build_cast (arg_type,
+ f.force_val (fold_build1 (
+ ABSU_EXPR, unsigned_type_for (arg_type), arg))));
+
+ auto ret = fold_build1 (ABS_EXPR, arg_type, arg);
+ if (this->call_properties (f) & CP_RAISE_FP_EXCEPTIONS)
+ {
+ f.assign (f.lhs, ret);
+ return build_optimization_barrier (f.lhs);
+ }
+ else
+ return gimple_build_assign (f.lhs, ret);
+ }
+};
+
+/* Build a tree representing the absolute difference between LHS and RHS.
+ For floating-point types, this is just `ABS (LHS - RHS)`.
+ For integer types, it is `.ABD (LHS, RHS)`. */
+tree
+build_abs_diff (gimple_folder &f, tree lhs, tree rhs)
+{
+ auto type = TREE_TYPE (lhs);
+
+ if (FLOAT_TYPE_P (type))
+ return fold_build1 (ABS_EXPR, type,
+ f.force_val (fold_build2 (MINUS_EXPR, type, lhs, rhs)));
+
+ auto ret = create_tmp_var (type);
+ vec<tree> args{};
+ args.safe_push (lhs);
+ args.safe_push (rhs);
+ auto call = gimple_build_call_internal_vec (IFN_ABD, args);
+ gsi_insert_before (f.gsi, call, GSI_SAME_STMT);
+ gimple_call_set_lhs (call, ret);
+ return ret;
+}
+
+struct gimple_abs_diff : public gimple_function_base
+{
+ unsigned call_properties (const function_instance &fi) const override
+ {
+ return (flag_trapping_math && fi.type_suffix (0).tclass == TYPE_float)
+ ? CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS
+ : 0;
+ }
+
+ gimple *fold (gimple_folder &f) const override
+ {
+ auto lhs = gimple_call_arg (f.call, 0);
+ auto rhs = gimple_call_arg (f.call, 1);
+ auto ret = build_abs_diff (f, lhs, rhs);
+ if (this->call_properties (f) & CP_RAISE_FP_EXCEPTIONS)
+ {
+ f.assign (f.lhs, ret);
+ return build_optimization_barrier (f.lhs);
+ }
+ else
+ return gimple_build_assign (f.lhs, ret);
+ }
+};
+
+struct gimple_abs_diff_accumulate : public gimple_function_base
+{
+ unsigned call_properties (const function_instance &fi) const override
+ {
+ return (flag_trapping_math && fi.type_suffix (0).tclass == TYPE_float)
+ ? CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS
+ : 0;
+ }
+
+ gimple *fold (gimple_folder &f) const override
+ {
+ auto accumulator = gimple_call_arg (f.call, 0);
+ auto lhs = gimple_call_arg (f.call, 1);
+ auto rhs = gimple_call_arg (f.call, 2);
+ auto abs_diff = f.force_val (build_abs_diff (f, lhs, rhs));
+ auto ret
+ = fold_build2 (PLUS_EXPR, TREE_TYPE (accumulator), accumulator,
abs_diff);
+
+ if (this->call_properties (f) & CP_RAISE_FP_EXCEPTIONS)
+ {
+ f.assign (f.lhs, ret);
+ return build_optimization_barrier (f.lhs);
+ }
+ else
+ return gimple_build_assign (f.lhs, ret);
+ }
+};
+
// Reinterpret
NEON_FUNCTION (vreinterpret, vreinterpretq, gimple_reinterpret,)
@@ -840,6 +945,7 @@ NEON_FUNCTION (vsub, vsubq, vsubd, gimple_arith,
(MINUS_EXPR))
NEON_FUNCTION (vmul, vmulq, gimple_arith, (MULT_EXPR))
NEON_FUNCTION (vdiv, vdivq, gimple_arith, (RDIV_EXPR))
NEON_FUNCTION (vneg, vnegq, vnegd, gimple_arith, (NEGATE_EXPR))
+NEON_FUNCTION (vabs, vabsq, vabsd, gimple_abs,)
// Bitwise operations
NEON_FUNCTION (vand, 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 dc8653ac05b..3dd7763a67d 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
@@ -93,6 +93,13 @@ DEF_NEON_FUNCTION (vneg, all_signed, ("D0,D0"))
DEF_NEON_FUNCTION (vnegq, all_signed, ("Q0,Q0"))
DEF_NEON_FUNCTION (vneg, sd_float, ("D0,D0"))
DEF_NEON_FUNCTION (vnegq, sd_float, ("Q0,Q0"))
+
+// Absolute value
+DEF_NEON_FUNCTION (vabsd, d_signed, ("s0,s0"))
+DEF_NEON_FUNCTION (vabs, all_signed, ("D0,D0"))
+DEF_NEON_FUNCTION (vabsq, all_signed, ("Q0,Q0"))
+DEF_NEON_FUNCTION (vabs, sd_float, ("D0,D0"))
+DEF_NEON_FUNCTION (vabsq, sd_float, ("Q0,Q0"))
#undef REQUIRED_EXTENSIONS
// Lanewise arithmetic (FP16)
@@ -116,6 +123,10 @@ DEF_NEON_FUNCTION (vdivq, h_float, ("Q0,Q0,Q0"))
// Negation
DEF_NEON_FUNCTION (vneg, h_float, ("D0,D0"))
DEF_NEON_FUNCTION (vnegq, h_float, ("Q0,Q0"))
+
+// Absolute value
+DEF_NEON_FUNCTION (vabs, h_float, ("D0,D0"))
+DEF_NEON_FUNCTION (vabsq, h_float, ("Q0,Q0"))
#undef REQUIRED_EXTENSIONS
// Bitwise operations
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def
b/gcc/config/aarch64/aarch64-simd-builtins.def
index 9c61cc05a05..ff6ced34deb 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -668,12 +668,6 @@
BUILTIN_VHSDF (UNOP, frecpe, 0, FP)
BUILTIN_VHSDF_HSDF (BINOP, frecps, 0, FP)
- /* Implemented by a mixture of abs2 patterns. Note the DImode builtin is
- only ever used for the int64x1_t intrinsic, there is no scalar version.
*/
- BUILTIN_VSDQ_I_DI (UNOP, abs, 0, QUIET)
- BUILTIN_VHSDF (UNOP, abs, 2, QUIET)
- VAR1 (UNOP, abs, 2, QUIET, hf)
-
BUILTIN_VQ_HSF (UNOP, vec_unpacks_hi_, 10, FP)
VAR1 (BINOP, float_truncate_hi_, 0, FP, v4sf)
VAR1 (BINOP, float_truncate_hi_, 0, FP, v8hf)
diff --git a/gcc/config/aarch64/aarch64-simd.md
b/gcc/config/aarch64/aarch64-simd.md
index fe6cb4250f6..5cd4c66276f 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -974,19 +974,6 @@ (define_insn "abs<mode>2<vczle><vczbe>"
[(set_attr "type" "neon_abs<q>")]
)
-;; The intrinsic version of integer ABS must not be allowed to
-;; combine with any operation with an integrated ABS step, such
-;; as SABD.
-(define_insn "aarch64_abs<mode><vczle><vczbe>"
- [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (unspec:VSDQ_I_DI
- [(match_operand:VSDQ_I_DI 1 "register_operand" "w")]
- UNSPEC_ABS))]
- "TARGET_SIMD"
- "abs\t%<v>0<Vmtype>, %<v>1<Vmtype>"
- [(set_attr "type" "neon_abs<q>")]
-)
-
;; It's tempting to represent SABD as ABS (MINUS op1 op2).
;; This isn't accurate as ABS treats always its input as a signed value.
;; So (ABS:QI (minus:QI 64 -128)) == (ABS:QI (192 or -64 signed)) == 64.
@@ -1318,9 +1305,8 @@ (define_insn "aarch64_<su>aba<mode><vczle><vczbe>"
(define_insn_and_split "*aarch64_abs_plus<mode>"
[(set (match_operand:VDQ_BHSI 0 "register_operand" "=&w")
(plus:VDQ_BHSI
- (unspec:VDQ_BHSI
- [(match_operand:VDQ_BHSI 1 "register_operand" "w")]
- UNSPEC_ABS)
+ (abs:VDQ_BHSI
+ (match_operand:VDQ_BHSI 1 "register_operand" "w"))
(match_operand:VDQ_BHSI 2 "register_operand" "w")))]
"TARGET_SIMD && can_create_pseudo_p ()"
"#"
diff --git a/gcc/config/aarch64/arm_fp16.h b/gcc/config/aarch64/arm_fp16.h
index c6356fdc78b..f67a9e19988 100644
--- a/gcc/config/aarch64/arm_fp16.h
+++ b/gcc/config/aarch64/arm_fp16.h
@@ -40,7 +40,7 @@ __extension__ extern __inline float16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vabsh_f16 (float16_t __a)
{
- return __builtin_aarch64_abshf (__a);
+ return __builtin_fabs (__a);
}
__extension__ extern __inline uint16_t
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 5c1a145f72e..b4ce93f8219 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -4901,104 +4901,6 @@ vabdq_f64 (float64x2_t __a, float64x2_t __b)
return __builtin_aarch64_fabdv2df (__a, __b);
}
-/* vabs */
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_f32 (float32x2_t __a)
-{
- return __builtin_aarch64_absv2sf (__a);
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_f64 (float64x1_t __a)
-{
- return (float64x1_t) {__builtin_fabs (__a[0])};
-}
-
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_s8 (int8x8_t __a)
-{
- return __builtin_aarch64_absv8qi (__a);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_s16 (int16x4_t __a)
-{
- return __builtin_aarch64_absv4hi (__a);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_s32 (int32x2_t __a)
-{
- return __builtin_aarch64_absv2si (__a);
-}
-
-__extension__ extern __inline int64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_s64 (int64x1_t __a)
-{
- return (int64x1_t) {__builtin_aarch64_absdi (__a[0])};
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_f32 (float32x4_t __a)
-{
- return __builtin_aarch64_absv4sf (__a);
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_f64 (float64x2_t __a)
-{
- return __builtin_aarch64_absv2df (__a);
-}
-
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_s8 (int8x16_t __a)
-{
- return __builtin_aarch64_absv16qi (__a);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_s16 (int16x8_t __a)
-{
- return __builtin_aarch64_absv8hi (__a);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_s32 (int32x4_t __a)
-{
- return __builtin_aarch64_absv4si (__a);
-}
-
-__extension__ extern __inline int64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_s64 (int64x2_t __a)
-{
- return __builtin_aarch64_absv2di (__a);
-}
-
-/* Try to avoid moving between integer and vector registers.
- For why the cast to unsigned is needed check the vnegd_s64 intrinsic.
- There is a testcase related to this issue:
- gcc.target/aarch64/vabsd_s64.c. */
-
-__extension__ extern __inline int64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsd_s64 (int64_t __a)
-{
- return __a < 0 ? - (uint64_t) __a : __a;
-}
-
/* vaddv */
__extension__ extern __inline int8_t
@@ -19356,20 +19258,6 @@ vuqaddd_s64 (int64_t __a, uint64_t __b)
/* ARMv8.2-A FP16 one operand vector intrinsics. */
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabs_f16 (float16x4_t __a)
-{
- return __builtin_aarch64_absv4hf (__a);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabsq_f16 (float16x8_t __a)
-{
- return __builtin_aarch64_absv8hf (__a);
-}
-
__extension__ extern __inline uint16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vceqz_f16 (float16x4_t __a)
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 8ed91d021f0..18844b0aeca 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -914,7 +914,6 @@ (define_c_enum "unspec"
[
UNSPEC_ASHIFT_SIGNED ; Used in aarch-simd.md.
UNSPEC_ASHIFT_UNSIGNED ; Used in aarch64-simd.md.
- UNSPEC_ABS ; Used in aarch64-simd.md.
UNSPEC_FCVTN_FP8 ; Used in aarch64-simd.md.
UNSPEC_FCVTN2_FP8 ; Used in aarch64-builtins.cc.
UNSPEC_F1CVTL_FP8 ; Used in aarch64-simd.md.
diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c
b/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c
index 43c37e21b50..9af313f4220 100644
--- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3" } */
+/* { dg-options "-O3 -fno-trapping-math" } */
/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
#pragma GCC target "+nosve"
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/trapping_math.c
b/gcc/testsuite/gcc.target/aarch64/neon/trapping_math.c
index 0f56da59c12..9ad49b58042 100644
--- a/gcc/testsuite/gcc.target/aarch64/neon/trapping_math.c
+++ b/gcc/testsuite/gcc.target/aarch64/neon/trapping_math.c
@@ -72,3 +72,69 @@ test_vaddq_f64 (float64x2_t a, float64x2_t b)
{
vaddq_f64 (a, b);
}
+
+/*
+** test_vabs_f16:
+** fabs v[0-9]+\.4h, v0\.4h
+** ret
+*/
+void
+test_vabs_f16 (float16x4_t a)
+{
+ vabs_f16 (a);
+}
+
+/*
+** test_vabsq_f16:
+** fabs v[0-9]+\.8h, v0\.8h
+** ret
+*/
+void
+test_vabsq_f16 (float16x8_t a)
+{
+ vabsq_f16 (a);
+}
+
+/*
+** test_vabs_f32:
+** fabs v[0-9]+\.2s, v0\.2s
+** ret
+*/
+void
+test_vabs_f32 (float32x2_t a)
+{
+ vabs_f32 (a);
+}
+
+/*
+** test_vabsq_f32:
+** fabs v[0-9]+\.4s, v0\.4s
+** ret
+*/
+void
+test_vabsq_f32 (float32x4_t a)
+{
+ vabsq_f32 (a);
+}
+
+/*
+** test_vabs_f64:
+** fabs d[0-9]+, d0
+** ret
+*/
+void
+test_vabs_f64 (float64x1_t a)
+{
+ vabs_f64 (a);
+}
+
+/*
+** test_vabsq_f64:
+** fabs v[0-9]+\.2d, v0\.2d
+** ret
+*/
+void
+test_vabsq_f64 (float64x2_t a)
+{
+ vabsq_f64 (a);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vabs.c
b/gcc/testsuite/gcc.target/aarch64/neon/vabs.c
new file mode 100644
index 00000000000..3c9db51fdf0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vabs.c
@@ -0,0 +1,116 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vabs_f32:
+** fabs v0\.2s, v0\.2s
+** ret
+*/
+TEST_UNIFORM_UNARY (vabs_f32, float32x2_t)
+
+/*
+** test_vabs_f64:
+** fabs d0, d0
+** ret
+*/
+TEST_UNIFORM_UNARY (vabs_f64, float64x1_t)
+
+/*
+** test_vabs_s8:
+** abs v0\.8b, v0\.8b
+** ret
+*/
+TEST_UNIFORM_UNARY (vabs_s8, int8x8_t)
+
+/*
+** test_vabs_s16:
+** abs v0\.4h, v0\.4h
+** ret
+*/
+TEST_UNIFORM_UNARY (vabs_s16, int16x4_t)
+
+/*
+** test_vabs_s32:
+** abs v0\.2s, v0\.2s
+** ret
+*/
+TEST_UNIFORM_UNARY (vabs_s32, int32x2_t)
+
+// FIXME: Performs abs in scalar register, even though it requires extra moves:
+// fmov x31, d0
+// cmp x31, #?0
+// csneg x31, x31, x31, ge
+// fmov d0, x31
+
+/*
+** test_vabs_s64: { xfail *-*-* }
+** abs d0, d0
+** ret
+*/
+TEST_UNIFORM_UNARY (vabs_s64, int64x1_t)
+
+/*
+** test_vabsd_s64:
+** cmp x0, #?0
+** csneg x0, x0, x0, ge
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsd_s64, int64_t)
+
+/*
+** test_vabsq_f32:
+** fabs v0\.4s, v0\.4s
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsq_f32, float32x4_t)
+
+/*
+** test_vabsq_f64:
+** fabs v0\.2d, v0\.2d
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsq_f64, float64x2_t)
+
+/*
+** test_vabsq_s8:
+** abs v0\.16b, v0\.16b
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsq_s8, int8x16_t)
+
+/*
+** test_vabsq_s16:
+** abs v0\.8h, v0\.8h
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsq_s16, int16x8_t)
+
+/*
+** test_vabsq_s32:
+** abs v0\.4s, v0\.4s
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsq_s32, int32x4_t)
+
+/*
+** test_vabsq_s64:
+** abs v0\.2d, v0\.2d
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsq_s64, int64x2_t)
+
+/*
+** test_vabs_f16:
+** fabs v0\.4h, v0\.4h
+** ret
+*/
+TEST_UNIFORM_UNARY (vabs_f16, float16x4_t)
+
+/*
+** test_vabsq_f16:
+** fabs v0\.8h, v0\.8h
+** ret
+*/
+TEST_UNIFORM_UNARY (vabsq_f16, float16x8_t)
diff --git a/gcc/testsuite/gcc.target/aarch64/singleton_intrinsics_1.c
b/gcc/testsuite/gcc.target/aarch64/singleton_intrinsics_1.c
index 27360150b58..afa07c9c5fb 100644
--- a/gcc/testsuite/gcc.target/aarch64/singleton_intrinsics_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/singleton_intrinsics_1.c
@@ -19,7 +19,7 @@ test_vadd_s64 (int64x1_t a, int64x1_t b)
return vadd_s64 (a, b);
}
-/* { dg-final { scan-assembler-times "\\tabs\\td\[0-9\]+, d\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "\\tabs\\td\[0-9\]+, d\[0-9\]+" 1 } {
xfail *-*-* } } */
int64x1_t
test_vabs_s64 (int64x1_t a)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
index 03560008fda..67c49cabcf1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3" } */
+/* { dg-options "-O3 -fno-trapping-math" } */
/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
#include <arm_neon.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c
b/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c
index b18db7ec641..f21771bfe89 100644
--- a/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/vabs_intrinsic_1.c
@@ -13,8 +13,9 @@ static void
\
test_vabs##q##_##size (ETYPE (size) * res, \
const ETYPE (size) *in1) \
{ \
- VTYPE (size, lanes) a = vld1##q##_s##size (res); \
- VTYPE (size, lanes) b = vld1##q##_s##size (in1); \
+ /* Use volatile to prevent constant folding. */ \
+ volatile VTYPE (size, lanes) a = vld1##q##_s##size (res); \
+ volatile VTYPE (size, lanes) b = vld1##q##_s##size (in1); \
a = vabs##q##_s##size (b); \
vst1##q##_s##size (res, a); \
}
@@ -54,15 +55,11 @@ test_##size (void)
\
ETYPE (size) res2[lanes_128] = {0}; \
ETYPE (size) expected2[lanes_128] = EXPECTED##lanes_128; \
\
- /* Forcefully avoid optimization. */ \
- asm volatile ("" : : : "memory"); \
test_vabs_##size (res1, pool1); \
for (i = 0; i < lanes_64; i++) \
if (res1[i] != expected1[i]) \
abort (); \
\
- /* Forcefully avoid optimization. */ \
- asm volatile ("" : : : "memory"); \
test_vabsq_##size (res2, pool2); \
for (i = 0; i < lanes_128; i++) \
if (res2[i] != expected2[i]) \
--
2.51.0