[AArch64] Fix register clobber in, aarch64_ashr_sisd_or_int_<mode>3 split.
authorMarcus Shawcroft <marcus.shawcroft@arm.com>
Mon, 30 Jun 2014 07:54:59 +0000 (07:54 +0000)
committerMarcus Shawcroft <mshawcroft@gcc.gnu.org>
Mon, 30 Jun 2014 07:54:59 +0000 (07:54 +0000)
PR target/61633

The two split patterns associated with
aarch64_ashr_sisd_or_int_<mode>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  <marcus.shawcroft@arm.com>

       PR target/61633
       * config/aarch64/aarch64.md (*aarch64_ashr_sisd_or_int_<mode>3):
       Add alternative; make early clobber.  Adjust both split patterns
       to use operand 0 as the working register.

From-SVN: r212137

gcc/ChangeLog
gcc/config/aarch64/aarch64.md

index a316102..894cae8 100644 (file)
@@ -1,3 +1,10 @@
+2014-06-30  Marcus Shawcroft  <marcus.shawcroft@arm.com>
+
+       PR target/61633
+       * config/aarch64/aarch64.md (*aarch64_ashr_sisd_or_int_<mode>3):
+       Add alternative; make early clobber.  Adjust both split patterns
+       to use operand 0 as the working register.
+
 2014-06-30  Jakub Jelinek  <jakub@redhat.com>
 
        * ira-build.c (sort_conflict_id_map): Don't call
index 8705ee9..3eb783c 100644 (file)
 
 ;; Arithmetic right shift using SISD or Integer instruction
 (define_insn "*aarch64_ashr_sisd_or_int_<mode>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<cmode>,w,rUs<cmode>")))]
+          (match_operand:GPI 1 "register_operand" "w,w,w,r")
+          (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
   ""
   "@
    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
    #
+   #
    asr\t%<w>0, %<w>1, %<w>2"
-  [(set_attr "simd" "yes,yes,no")
-   (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
+  [(set_attr "simd" "yes,yes,yes,no")
+   (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
 )
 
 (define_split
            (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
            (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"