ok. David
On Wed, Jun 17, 2015 at 3:06 PM, Carrot Wei <car...@google.com> wrote: > Hi > > In aarch64 backend of google/4.9 branch, the split pattern for insn > aarch64_lshr_sisd_or_int_<mode>3 destroys one of the source operands, > causes the later usage of the operand get a wrong value (google bug > 17907351). > > The bug has been fixed in trunk by r220860. This patch backports it to > google/4.9 branch. It passed regression test on aarch64-qemu. > > OK for google/4.9? > > thanks > Guozhi Wei > > > Index: config/aarch64/aarch64.md > =================================================================== > --- config/aarch64/aarch64.md (revision 224524) > +++ config/aarch64/aarch64.md (working copy) > @@ -2786,7 +2786,7 @@ > > ;; Logical right shift using SISD or Integer instruction > (define_insn "*aarch64_lshr_sisd_or_int_<mode>3" > - [(set (match_operand:GPI 0 "register_operand" "=w,w,r") > + [(set (match_operand:GPI 0 "register_operand" "=w,&w,r") > (lshiftrt:GPI > (match_operand:GPI 1 "register_operand" "w,w,r") > (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" > "Us<cmode>,w,rUs<cmode>")))] > @@ -2805,11 +2805,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_USHL))] > - "" > + (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))] > + { > + operands[3] = gen_lowpart (QImode, operands[0]); > + } > ) > > (define_split > @@ -2818,11 +2820,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_USHL_2S))] > - "" > + (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))] > + { > + operands[3] = gen_lowpart (QImode, operands[0]); > + } > ) > > ;; Arithmetic right shift using SISD or Integer instruction > Index: testsuite/gcc.target/aarch64/sisd-shft-neg_1.c > =================================================================== > --- testsuite/gcc.target/aarch64/sisd-shft-neg_1.c (revision 0) > +++ testsuite/gcc.target/aarch64/sisd-shft-neg_1.c (working copy) > @@ -0,0 +1,38 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 -fno-inline" } */ > + > +extern void abort (void); > + > +#define force_simd_si(v) asm volatile ("mov %s0, %1.s[0]" :"=w" (v) :"w" (v) > :) > + > +unsigned int > +shft_add (unsigned int a, unsigned int b) > +{ > + unsigned int c; > + > + force_simd_si (a); > + force_simd_si (b); > + c = a >> b; > + force_simd_si (c); > + > + return c + b; > +} > + > +int > +main (void) > +{ > + unsigned int i = 0; > + unsigned int a = 0xdeadbeef; > + > + for (i = 0; i < 32; i++) > + { > + unsigned int exp = (a / (1 << i) + i); > + unsigned int got = shft_add (a, i); > + > + if (exp != got) > + abort (); > + } > + > + return 0; > +} > +