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