This seems to have slipped under the radar for awhile. Ping.

--Alan

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

Reply via email to