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;
> +}
> +

Reply via email to