Implementing vmulx_* and vmulx_lane* NEON intrinsics Hi all,
This series of patches focuses on the different vmulx_ and vmulx_lane NEON intrinsics variants. All of the existing inlined assembly block implementations are replaced with newly defined __builtin functions, and the missing intrinsics are implemented with __builtins as well. The rationale for the change from assembly to __builtin is that the compiler would be able to do more optimisations like instruction scheduling. A new named md pattern was added for the new fmulx __builtin. Most vmulx_lane variants have been implemented as a combination of a vdup followed by a vmulx_, rather than as separate __builtins. The remaining vmulx_lane intrinsics (vmulx(s|d)_lane*) were implemented using __aarch64_vget_lane_any () and an appropriate vmulx. Four new nameless md patterns were added to replace all the different types of RTL generated from the combination of these intrinsics during the combine pass. The rationale for this change is that in this way we would be able to optimise away all uses of a dup followed by a fmulx to the appropriate fmulx lane variant instruction. New test cases were added for all the implemented intrinsics. Also new tests were added for the proper error reporting of out-of-bounds accesses to _lane intrinsics. Tested on targets aarch64-none-elf and aarch64_be-none-elf. Dependencies: patch 2/3 depends on patch 1/3, and patch 3/3 depends on patch 2/3. --- This patch from the series adds tests that check for the proper error reporting of out of bounds accesses to all the vmulx_lane NEON intrinsics variants. The tests were added separately from the previous patch in order to reduce its size. gcc/testsuite/ 2015-XX-XX Bilyan Borisov <bilyan.bori...@arm.com> * gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f32_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f64_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f32_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f64_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxd_lane_f64_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxd_laneq_f64_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f32_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f64_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f32_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f64_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxs_lane_f32_indices_1.c: New. * gcc.target/aarch64/advsimd-intrinsics/vmulxs_laneq_f32_indices_1.c: New.
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f32_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f32_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..5681d5d21bc62e54e308c0a7c171f6f1b8969b71 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f32_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float32x2_t +f_vmulx_lane_f32 (float32x2_t v1, float32x2_t v2) +{ + float32x2_t res; + /* { dg-error "lane -1 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulx_lane_f32 (v1, v2, -1); + /* { dg-error "lane 2 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulx_lane_f32 (v1, v2, 2); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f64_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f64_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..0c8f313d10423d6b189fe3c9081f0a6ef55f9937 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_lane_f64_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float64x1_t +f_vmulx_lane_f64 (float64x1_t v1, float64x1_t v2) +{ + float64x1_t res; + /* { dg-error "lane -1 out of range 0 - 0" "" { xfail arm*-*-* } 0 } */ + res = vmulx_lane_f64 (v1, v2, -1); + /* { dg-error "lane 1 out of range 0 - 0" "" { xfail arm*-*-* } 0 } */ + res = vmulx_lane_f64 (v1, v2, 1); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f32_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f32_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..9053ab6a7bd1bf9eba1d308ceed1524685e031e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f32_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float32x2_t +f_vmulx_laneq_f32 (float32x2_t v1, float32x4_t v2) +{ + float32x2_t res; + /* { dg-error "lane -1 out of range 0 - 3" "" { xfail arm*-*-* } 0 } */ + res = vmulx_laneq_f32 (v1, v2, -1); + /* { dg-error "lane 4 out of range 0 - 3" "" { xfail arm*-*-* } 0 } */ + res = vmulx_laneq_f32 (v1, v2, 4); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f64_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f64_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..6d5c8d6290250da8e446263b8da1b6841ea4105d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulx_laneq_f64_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float64x1_t +f_vmulx_laneq_f64 (float64x1_t v1, float64x2_t v2) +{ + float64x1_t res; + /* { dg-error "lane -1 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulx_laneq_f64 (v1, v2, -1); + /* { dg-error "lane 2 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulx_laneq_f64 (v1, v2, 2); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxd_lane_f64_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxd_lane_f64_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..463e46e237227b8c5cf0bf0bd23997e590268214 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxd_lane_f64_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float64_t +f_vmulxd_lane_f64 (float64_t v1, float64x1_t v2) +{ + float64_t res; + /* { dg-error "lane -1 out of range 0 - 0" "" { xfail arm*-*-* } 0 } */ + res = vmulxd_lane_f64 (v1, v2, -1); + /* { dg-error "lane 1 out of range 0 - 0" "" { xfail arm*-*-* } 0 } */ + res = vmulxd_lane_f64 (v1, v2, 1); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxd_laneq_f64_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxd_laneq_f64_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..f3c3c2fc19ef5ded599c996d8eafa8244b985ca6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxd_laneq_f64_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float64_t +f_vmulxd_laneq_f64 (float64_t v1, float64x2_t v2) +{ + float64_t res; + /* { dg-error "lane -1 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxd_laneq_f64 (v1, v2, -1); + /* { dg-error "lane 2 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxd_laneq_f64 (v1, v2, 2); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f32_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f32_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..2547f97fe44cdce4e65ca86b934cc56447146cd7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f32_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float32x4_t +f_vmulxq_lane_f32 (float32x4_t v1, float32x2_t v2) +{ + float32x4_t res; + /* { dg-error "lane -1 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_lane_f32 (v1, v2, -1); + /* { dg-error "lane 2 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_lane_f32 (v1, v2, 2); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f64_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f64_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..de783035d8fbcd9fc20ab5a36448d93b320be0cb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_lane_f64_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float64x2_t +f_vmulxq_lane_f64 (float64x2_t v1, float64x1_t v2) +{ + float64x2_t res; + /* { dg-error "lane -1 out of range 0 - 0" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_lane_f64 (v1, v2, -1); + /* { dg-error "lane 1 out of range 0 - 0" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_lane_f64 (v1, v2, 1); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f32_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f32_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..45406a74a900568b30c2dc7ed467835a58374ee8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f32_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float32x4_t +f_vmulxq_laneq_f32 (float32x4_t v1, float32x4_t v2) +{ + float32x4_t res; + /* { dg-error "lane -1 out of range 0 - 3" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_laneq_f32 (v1, v2, -1); + /* { dg-error "lane 4 out of range 0 - 3" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_laneq_f32 (v1, v2, 4); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f64_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f64_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..acc4826c3de356c8cde275e9dc8d93f08284445a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxq_laneq_f64_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float64x2_t +f_vmulxq_laneq_f64 (float64x2_t v1, float64x2_t v2) +{ + float64x2_t res; + /* { dg-error "lane -1 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_laneq_f64 (v1, v2, -1); + /* { dg-error "lane 2 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxq_laneq_f64 (v1, v2, 2); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxs_lane_f32_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxs_lane_f32_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..647927d3d41ed16ad1b98f3949c1c8ac8386a997 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxs_lane_f32_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float32_t +f_vmulxs_lane_f32 (float32_t v1, float32x2_t v2) +{ + float32_t res; + /* { dg-error "lane -1 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxs_lane_f32 (v1, v2, -1); + /* { dg-error "lane 2 out of range 0 - 1" "" { xfail arm*-*-* } 0 } */ + res = vmulxs_lane_f32 (v1, v2, 2); + return res; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxs_laneq_f32_indices_1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxs_laneq_f32_indices_1.c new file mode 100644 index 0000000000000000000000000000000000000000..8f680f75e33dd7c123809350d8b42d0cdfd9f6c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmulxs_laneq_f32_indices_1.c @@ -0,0 +1,16 @@ +#include <arm_neon.h> + +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ +/* { dg-skip-if "" { arm*-*-* } } */ + +float32_t +f_vmulxs_laneq_f32 (float32_t v1, float32x4_t v2) +{ + float32_t res; + /* { dg-error "lane -1 out of range 0 - 3" "" { xfail arm*-*-* } 0 } */ + res = vmulxs_laneq_f32 (v1, v2, -1); + /* { dg-error "lane 4 out of range 0 - 3" "" { xfail arm*-*-* } 0 } */ + res = vmulxs_laneq_f32 (v1, v2, 4); + return res; +}