[PATCH][AArch64] Vector shift by 64 fix

gcc/

	* config/aarch64/aarch64-simd-builtins.def (ashr): DI mode removed.
	(ashr_simd): New builtin handling DI mode.
	* config/aarch64/aarch64-simd.md (aarch64_ashr_simddi): New pattern.
	(aarch64_sshr_simddi): New match pattern.
	* config/aarch64/arm_neon.h (vshr_n_s32): Builtin call modified.
	(vshrd_n_s64): Likewise.
	* config/aarch64/predicates.md (aarch64_shift_imm64_di): New predicate.

gcc/testsuite/

	* gcc.target/aarch64/sshr64_1.c: New testcase.

From-SVN: r206978
This commit is contained in:
Alex Velenko 2014-01-23 16:24:13 +00:00 committed by James Greenhalgh
parent 949ad9715a
commit f9a4c9a613
8 changed files with 164 additions and 3 deletions

View File

@ -1,3 +1,13 @@
2014-01-23 Alex Velenko <Alex.Velenko@arm.com>
* config/aarch64/aarch64-simd-builtins.def (ashr): DI mode removed.
(ashr_simd): New builtin handling DI mode.
* config/aarch64/aarch64-simd.md (aarch64_ashr_simddi): New pattern.
(aarch64_sshr_simddi): New match pattern.
* config/aarch64/arm_neon.h (vshr_n_s32): Builtin call modified.
(vshrd_n_s64): Likewise.
* config/aarch64/predicates.md (aarch64_shift_imm64_di): New predicate.
2014-01-23 Nick Clifton <nickc@redhat.com>
* config/msp430/msp430.h (ASM_SPEC): Pass the -mcpu as -mcpu.

View File

@ -190,7 +190,8 @@
BUILTIN_VSDQ_I_DI (BINOP, srshl, 0)
BUILTIN_VSDQ_I_DI (BINOP, urshl, 0)
BUILTIN_VSDQ_I_DI (SHIFTIMM, ashr, 3)
BUILTIN_VDQ_I (SHIFTIMM, ashr, 3)
VAR1 (SHIFTIMM, ashr_simd, 0, di)
BUILTIN_VSDQ_I_DI (SHIFTIMM, lshr, 3)
/* Implemented by aarch64_<sur>shr_n<mode>. */
BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n, 0)

View File

@ -685,6 +685,32 @@
DONE;
})
;; DI vector shift
(define_expand "aarch64_ashr_simddi"
[(match_operand:DI 0 "register_operand" "=w")
(match_operand:DI 1 "register_operand" "w")
(match_operand:QI 2 "aarch64_shift_imm64_di" "")]
"TARGET_SIMD"
{
if (INTVAL (operands[2]) == 64)
emit_insn (gen_aarch64_sshr_simddi (operands[0], operands[1]));
else
emit_insn (gen_ashrdi3 (operands[0], operands[1], operands[2]));
DONE;
}
)
;; SIMD shift by 64. This pattern is a special case as standard pattern does
;; not handle NEON shifts by 64.
(define_insn "aarch64_sshr_simddi"
[(set (match_operand:DI 0 "register_operand" "=w")
(unspec:DI
[(match_operand:DI 1 "register_operand" "w")] UNSPEC_SSHR64))]
"TARGET_SIMD"
"sshr\t%d0, %d1, 64"
[(set_attr "type" "neon_shift_imm")]
)
(define_expand "vlshr<mode>3"
[(match_operand:VQ_S 0 "register_operand" "")
(match_operand:VQ_S 1 "register_operand" "")

View File

@ -93,6 +93,7 @@
UNSPEC_SISD_SSHL
UNSPEC_SISD_USHL
UNSPEC_SSHL_2S
UNSPEC_SSHR64
UNSPEC_ST1
UNSPEC_ST2
UNSPEC_ST3

View File

@ -23340,7 +23340,7 @@ vshr_n_s32 (int32x2_t __a, const int __b)
__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
vshr_n_s64 (int64x1_t __a, const int __b)
{
return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b);
return (int64x1_t) __builtin_aarch64_ashr_simddi (__a, __b);
}
__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
@ -23418,7 +23418,7 @@ vshrq_n_u64 (uint64x2_t __a, const int __b)
__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
vshrd_n_s64 (int64x1_t __a, const int __b)
{
return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b);
return (int64x1_t) __builtin_aarch64_ashr_simddi (__a, __b);
}
__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))

View File

@ -86,6 +86,10 @@
(and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64")))
(define_predicate "aarch64_shift_imm64_di"
(and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64")))
(define_predicate "aarch64_reg_or_shift_imm_si"
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_shift_imm_si")))

View File

@ -1,3 +1,7 @@
2014-01-23 Alex Velenko <Alex.Velenko@arm.com>
* gcc.target/aarch64/sshr64_1.c: New testcase.
2014-01-23 Balaji V. Iyer <balaji.v.iyer@intel.com>
* g++.dg/cilk-plus/cilk-plus.exp: Called the C/C++ common tests for

View File

@ -0,0 +1,115 @@
/* Test SIMD shift works correctly. */
/* { dg-do run } */
/* { dg-options "-O3 --save-temps" } */
#include "arm_neon.h"
extern void abort (void);
int __attribute__ ((noinline))
test_sshr64 ()
{
int64x1_t arg;
int64x1_t result;
int64_t got;
int64_t exp;
arg = vcreate_s64 (0x0000000080000000);
result = vshr_n_s64 (arg, 64);
got = vget_lane_s64 (result, 0);
exp = 0;
/* Expect: "result" = 0000000000000000. */
if (exp != got)
return 1;
return 0;
}
int __attribute__ ((noinline))
test_sshr64_neg ()
{
int64x1_t arg;
int64x1_t result;
int64_t got;
int64_t exp;
arg = vcreate_s64 (0xffffffff80000000);
result = vshr_n_s64 (arg, 64);
got = vget_lane_s64 (result, 0);
exp = 0xffffffffffffffff;
/* Expect: "result" = -1. */
if (exp != got)
return 1;
return 0;
}
int
__attribute__ ((noinline))
test_other ()
{
int64x1_t arg;
int64x1_t result;
int64_t got;
int64_t exp;
arg = vcreate_s64 (0x0000000080000000);
result = vshr_n_s64 (arg, 4);
got = vget_lane_s64 (result, 0);
exp = 0x0000000008000000;
/* Expect: "result" = 0x0000000008000000. */
if (exp != got)
return 1;
return 0;
}
int __attribute__ ((noinline))
test_other_neg ()
{
int64x1_t arg;
int64x1_t result;
int64_t got;
int64_t exp;
arg = vcreate_s64 (0xffffffff80000000);
result = vshr_n_s64 (arg, 4);
got = vget_lane_s64 (result, 0);
exp = 0xfffffffff8000000;
/* Expect: "result" = 0xfffffffff8000000. */
if (exp != got)
return 1;
return 0;
}
int __attribute__ ((noinline))
test_no_sshr0 ()
{
int64x1_t arg;
int64x1_t result;
int64_t got;
int64_t exp;
arg = vcreate_s64 (0x0000000080000000);
result = vshr_n_s64 (arg, 0);
got = vget_lane_s64 (result, 0);
exp = 0x0000000080000000;
/* Expect: "result" = 0x0000000080000000. */
if (exp != got)
return 1;
return 0;
}
/* { dg-final { scan-assembler-not "sshr\\td\[0-9\]+, d\[0-9\]+, 0" } } */
int
main ()
{
if (test_sshr64 ())
abort ();
if (test_other ())
abort ();
if (test_sshr64_neg ())
abort ();
if (test_other_neg ())
abort ();
if (test_no_sshr0 ())
abort ();
return 0;
}
/* { dg-final { cleanup-saved-temps } } */