From 21a7b5e1dbb59c6ff055aa3240e52916790ec305 Mon Sep 17 00:00:00 2001 From: Marcus Shawcroft Date: Mon, 30 Jun 2014 07:54:59 +0000 Subject: [PATCH] [AArch64] Fix register clobber in, aarch64_ashr_sisd_or_int_3 split. PR target/61633 The two split patterns associated with aarch64_ashr_sisd_or_int_3 split the instruction into a NEG followed by an SHL. The split uses one of the input operands as a scratch register to hold the output of the NEG resulting in register corruption. This patch adjusts the splits to use the output operand as the scratch register. 2014-06-30 Marcus Shawcroft PR target/61633 * config/aarch64/aarch64.md (*aarch64_ashr_sisd_or_int_3): Add alternative; make early clobber. Adjust both split patterns to use operand 0 as the working register. From-SVN: r212137 --- gcc/ChangeLog | 7 +++++++ gcc/config/aarch64/aarch64.md | 27 ++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a316102..894cae8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-06-30 Marcus Shawcroft + + PR target/61633 + * config/aarch64/aarch64.md (*aarch64_ashr_sisd_or_int_3): + Add alternative; make early clobber. Adjust both split patterns + to use operand 0 as the working register. + 2014-06-30 Jakub Jelinek * ira-build.c (sort_conflict_id_map): Don't call diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 8705ee9..3eb783c 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -3057,17 +3057,18 @@ ;; Arithmetic right shift using SISD or Integer instruction (define_insn "*aarch64_ashr_sisd_or_int_3" - [(set (match_operand:GPI 0 "register_operand" "=w,w,r") + [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r") (ashiftrt:GPI - (match_operand:GPI 1 "register_operand" "w,w,r") - (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us,w,rUs")))] + (match_operand:GPI 1 "register_operand" "w,w,w,r") + (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us,w,0,rUs")))] "" "@ sshr\t%0, %1, %2 # + # asr\t%0, %1, %2" - [(set_attr "simd" "yes,yes,no") - (set_attr "type" "neon_shift_imm,neon_shift_reg,shift_reg")] + [(set_attr "simd" "yes,yes,yes,no") + (set_attr "type" "neon_shift_imm,neon_shift_reg,neon_shift_reg,shift_reg")] ) (define_split @@ -3076,11 +3077,13 @@ (match_operand:DI 1 "aarch64_simd_register") (match_operand:QI 2 "aarch64_simd_register")))] "TARGET_SIMD && reload_completed" - [(set (match_dup 2) + [(set (match_dup 3) (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) (set (match_dup 0) - (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))] - "" + (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))] +{ + operands[3] = gen_lowpart (QImode, operands[0]); +} ) (define_split @@ -3089,11 +3092,13 @@ (match_operand:SI 1 "aarch64_simd_register") (match_operand:QI 2 "aarch64_simd_register")))] "TARGET_SIMD && reload_completed" - [(set (match_dup 2) + [(set (match_dup 3) (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) (set (match_dup 0) - (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))] - "" + (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))] +{ + operands[3] = gen_lowpart (QImode, operands[0]); +} ) (define_insn "*aarch64_sisd_ushl" -- 2.7.4