Port the `vmul` family of NEON intrinsics to pragma-based framework, and
add assembly tests for every variant.
gcc/ChangeLog:
* config/aarch64/aarch64-neon-builtins-base.cc (vmulh, vmul,
vmulq): New function bases.
* config/aarch64/aarch64-neon-builtins-base.def (vmul, vmulq,
vmulh): New function declarations.
* config/aarch64/arm_neon.h (vmul_s8, vmul_s16, vmul_s32,
vmul_f32, vmul_f64, vmul_u8, vmul_u16, vmul_u32, vmulq_s8,
vmulq_s16, vmulq_s32, vmulq_f32, vmulq_f64, vmulq_u8,
vmulq_u16, vmulq_u32, vmul_f16, vmulq_f16): Delete function
definitions.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/neon/vmul.c: New test.
---
.../aarch64/aarch64-neon-builtins-base.cc | 4 +
.../aarch64/aarch64-neon-builtins-base.def | 10 ++
gcc/config/aarch64/arm_neon.h | 126 -----------------
gcc/testsuite/gcc.target/aarch64/neon/vmul.c | 130 ++++++++++++++++++
4 files changed, 144 insertions(+), 126 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vmul.c
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
index 9952a85f646..2eab81c6bcc 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
@@ -814,6 +814,10 @@ NEON_FUNCTION (vsubd, gimple_arith, (MINUS_EXPR))
NEON_FUNCTION (vsub, gimple_arith, (MINUS_EXPR))
NEON_FUNCTION (vsubq, gimple_arith, (MINUS_EXPR))
+// Multiplication
+NEON_FUNCTION (vmul, gimple_arith, (MULT_EXPR))
+NEON_FUNCTION (vmulq, gimple_arith, (MULT_EXPR))
+
// 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 6d55056ce4e..c8a67619055 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
@@ -76,6 +76,12 @@ DEF_NEON_FUNCTION (vaddq, bhdq_poly, ("Q0,Q0,Q0"))
DEF_NEON_FUNCTION (vsubd, d_integer, ("s0,s0,s0"))
DEF_NEON_FUNCTION (vsub, all_arith_no_fp16, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vsubq, all_arith_no_fp16, ("Q0,Q0,Q0"))
+
+// Multiplication
+DEF_NEON_FUNCTION (vmul, bhs_integer, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmulq, bhs_integer, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vmul, sd_float, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmulq, sd_float, ("Q0,Q0,Q0"))
#undef REQUIRED_EXTENSIONS
// Lanewise arithmetic (FP16)
@@ -87,6 +93,10 @@ DEF_NEON_FUNCTION (vaddq, h_float, ("Q0,Q0,Q0"))
// Subtraction
DEF_NEON_FUNCTION (vsub, h_float, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vsubq, h_float, ("Q0,Q0,Q0"))
+
+// Multiplication
+DEF_NEON_FUNCTION (vmul, h_float, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmulq, h_float, ("Q0,Q0,Q0"))
#undef REQUIRED_EXTENSIONS
// Bitwise operations
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 1051b24b5e0..1abdd525d07 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -637,62 +637,6 @@ vdivq_f64 (float64x2_t __a, float64x2_t __b)
return __a / __b;
}
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_s8 (int8x8_t __a, int8x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_s16 (int16x4_t __a, int16x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_s32 (int32x2_t __a, int32x2_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_f32 (float32x2_t __a, float32x2_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_f64 (float64x1_t __a, float64x1_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_u8 (uint8x8_t __a, uint8x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_u16 (uint16x4_t __a, uint16x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_u32 (uint32x2_t __a, uint32x2_t __b)
-{
- return __a * __b;
-}
-
__extension__ extern __inline poly8x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmul_p8 (poly8x8_t __a, poly8x8_t __b)
@@ -700,62 +644,6 @@ vmul_p8 (poly8x8_t __a, poly8x8_t __b)
return __builtin_aarch64_pmulv8qi_ppp (__a, __b);
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_s8 (int8x16_t __a, int8x16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_s16 (int16x8_t __a, int16x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_s32 (int32x4_t __a, int32x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_f32 (float32x4_t __a, float32x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_f64 (float64x2_t __a, float64x2_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_u8 (uint8x16_t __a, uint8x16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_u16 (uint16x8_t __a, uint16x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_u32 (uint32x4_t __a, uint32x4_t __b)
-{
- return __a * __b;
-}
-
__extension__ extern __inline poly8x16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmulq_p8 (poly8x16_t __a, poly8x16_t __b)
@@ -20275,20 +20163,6 @@ vminnmq_f16 (float16x8_t __a, float16x8_t __b)
return __builtin_aarch64_fminv8hf (__a, __b);
}
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_f16 (float16x4_t __a, float16x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_f16 (float16x8_t __a, float16x8_t __b)
-{
- return __a * __b;
-}
-
__extension__ extern __inline float16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmulx_f16 (float16x4_t __a, float16x4_t __b)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vmul.c
b/gcc/testsuite/gcc.target/aarch64/neon/vmul.c
new file mode 100644
index 00000000000..74f1ebcc921
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vmul.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vmul_s8:
+** mul v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_s8, int8x8_t)
+
+/*
+** test_vmulq_s8:
+** mul v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_s8, int8x16_t)
+
+/*
+** test_vmul_s16:
+** mul v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_s16, int16x4_t)
+
+/*
+** test_vmulq_s16:
+** mul v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_s16, int16x8_t)
+
+/*
+** test_vmul_s32:
+** mul v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_s32, int32x2_t)
+
+/*
+** test_vmulq_s32:
+** mul v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_s32, int32x4_t)
+
+/*
+** test_vmul_u8:
+** mul v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_u8, uint8x8_t)
+
+/*
+** test_vmulq_u8:
+** mul v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_u8, uint8x16_t)
+
+/*
+** test_vmul_u16:
+** mul v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_u16, uint16x4_t)
+
+/*
+** test_vmulq_u16:
+** mul v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_u16, uint16x8_t)
+
+/*
+** test_vmul_u32:
+** mul v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_u32, uint32x2_t)
+
+/*
+** test_vmulq_u32:
+** mul v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_u32, uint32x4_t)
+
+/*
+** test_vmul_f32:
+** fmul v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_f32, float32x2_t)
+
+/*
+** test_vmulq_f32:
+** fmul v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_f32, float32x4_t)
+
+/*
+** test_vmul_f64:
+** fmul d0, (d0, d1|d1, d0)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_f64, float64x1_t)
+
+/*
+** test_vmulq_f64:
+** fmul v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_f64, float64x2_t)
+
+/*
+** test_vmul_f16:
+** fmul v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_f16, float16x4_t)
+
+/*
+** test_vmulq_f16:
+** fmul v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_f16, float16x8_t)
--
2.51.0