Patch attached.
Alan Lawrence wrote:
The sshr_n_64 intrinsics allow performing a signed shift right by 64 places. The
standard ashrdi3 pattern masks the sign amount with 63, so cannot be used.
However, such a shift fills the result by the sign bit, which is identical to
shifting right by 63. This patch just simplifies the code to shift by 63
instead, which allows to remove an UNSPEC and insn previously dedicated to this
case.
Cross-tested on aarch64-none-elf and aarch64_be-none-elf, with test coverage
provided by gcc.target/aarch64/sshr64_1.c .
gcc/ChangeLog:
* config/aarch64/aarch64.md (enum "unspec"): Remove UNSPEC_SSHR64.
* config/aarch64/aarch64-simd.md (aarch64_ashr_simddi): Change shift
amount to 63 if was 64.
(aarch64_sshr_simddi): Remove.
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index d493054b703c5698b771ce32d613e28d7c7b7b49..9cacdb1d40840952632532f5a356bbce4d611581 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -700,25 +700,16 @@
(match_operand:SI 2 "aarch64_shift_imm64_di" "")]
"TARGET_SIMD"
{
+ /* An arithmetic shift right by 64 fills the result with copies of the sign
+ bit, just like asr by 63 - however the standard pattern does not handle
+ a shift by 64. */
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]));
+ operands[2] = GEN_INT (63);
+ 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" "")
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 736da80b2705d02793433e6cdbcd422bfecc76f4..2b519c50360dd774298d7d97572e82e5424b843f 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -100,7 +100,6 @@
UNSPEC_SISD_SSHL
UNSPEC_SISD_USHL
UNSPEC_SSHL_2S
- UNSPEC_SSHR64
UNSPEC_ST1
UNSPEC_ST2
UNSPEC_ST3