aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/simplify-rtx.cc11
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/low-high-combine_1.c28
2 files changed, 39 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 21b7eb4..9c68d36 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -4860,6 +4860,17 @@ simplify_ashift:
return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
gen_rtx_PARALLEL (VOIDmode, vec));
}
+ /* (vec_concat:
+ (subreg_lowpart:N OP)
+ (vec_select:N OP P)) --> OP when P selects the high half
+ of the OP. */
+ if (GET_CODE (trueop0) == SUBREG
+ && subreg_lowpart_p (trueop0)
+ && GET_CODE (trueop1) == VEC_SELECT
+ && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
+ && !side_effects_p (XEXP (trueop1, 0))
+ && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
+ return XEXP (trueop1, 0);
}
return 0;
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/low-high-combine_1.c b/gcc/testsuite/gcc.target/aarch64/simd/low-high-combine_1.c
new file mode 100644
index 0000000..0b502d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/low-high-combine_1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_neon.h>
+
+/*
+** foo_le: { target aarch64_little_endian }
+** ret
+*/
+
+int32x4_t
+foo_le (int32x4_t a)
+{
+ return vcombine_s32 (vget_low_s32 (a), vget_high_s32 (a));
+}
+
+/*
+** foo_be: { target aarch64_big_endian }
+** ret
+*/
+
+int32x4_t
+foo_be (int32x4_t a)
+{
+ return vcombine_s32 (vget_high_s32 (a), vget_low_s32 (a));
+}
+