On 29/04/2019 17:58, Srinath Parvathaneni wrote:
> Hi All,
> 
> This patch is to fix the ICE caused by expand pattern of copysignf 
> builtin. This is a back port to r267019 of trunk.
> 
> Bootstrapped on aarch64-none-linux-gnu and regression tested on 
> aarch64-none-elf.
> 
> Ok for gcc 7 branch? If ok, could someone please commit the patch on my 
> behalf, I don't have commit rights.

Applied.

R.

> 
> *** gcc/ChangeLog ***
> 
> 2019-04-29  Srinath Parvathaneni  <srinath.parvathan...@arm.com>
> 
>       PR target/90075
>       * config/aarch64/iterators.md (V_INT_EQUIV): Add mode for
>       integer equivalent of floating point values.
> 
>       Backport from mainline
>       2018-12-11  Richard Earnshaw <richard.earns...@arm.com>
> 
>       PR target/37369
>       * config/aarch64/iterators.md (sizem1): Add sizes for
>       SFmode and DFmode.
>       (Vbtype): Add SFmode mapping.
>       * config/aarch64/aarch64.md (copysigndf3, copysignsf3): Delete.
>       (copysign<GPF:mode>3): New expand pattern.
>       (copysign<GPF:mode>3_insn): New insn pattern.
> 
> *** gcc/testsuite/ChangeLog ***
> 
> 2019-04-29  Srinath Parvathaneni  <srinath.parvathan...@arm.com>
> 
>       PR target/90075
>       * gcc.target/aarch64/pr90075.c: New test.
> 
> 
> rb11119.patch
> 
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 
> 4c4e144587e6daa8e577477460594ebd66dbdf33..90f9ee658c5cc2eb0477502b3f9e2f60b7b23efd
>  100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -140,6 +140,7 @@
>      UNSPEC_RSQRTS
>      UNSPEC_NZCV
>      UNSPEC_XPACLRI
> +    UNSPEC_COPYSIGN
>  ])
>  
>  (define_c_enum "unspecv" [
> @@ -5003,45 +5004,45 @@
>  ;;   LDR d2, #(1 << 63)
>  ;;   BSL v2.8b, [y], [x]
>  ;;
> -;; or another, equivalent, sequence using one of BSL/BIT/BIF.
> -;; aarch64_simd_bsldf will select the best suited of these instructions
> -;; to generate based on register allocation, and knows how to partially
> -;; constant fold based on the values of X and Y, so expand through that.
> -
> -(define_expand "copysigndf3"
> -  [(match_operand:DF 0 "register_operand")
> -   (match_operand:DF 1 "register_operand")
> -   (match_operand:DF 2 "register_operand")]
> +;; or another, equivalent, sequence using one of BSL/BIT/BIF.  Because
> +;; we expect these operations to nearly always operate on
> +;; floating-point values, we do not want the operation to be
> +;; simplified into a bit-field insert operation that operates on the
> +;; integer side, since typically that would involve three inter-bank
> +;; register copies.  As we do not expect copysign to be followed by
> +;; other logical operations on the result, it seems preferable to keep
> +;; this as an unspec operation, rather than exposing the underlying
> +;; logic to the compiler.
> +
> +(define_expand "copysign<GPF:mode>3"
> +  [(match_operand:GPF 0 "register_operand")
> +   (match_operand:GPF 1 "register_operand")
> +   (match_operand:GPF 2 "register_operand")]
>    "TARGET_FLOAT && TARGET_SIMD"
>  {
> -  rtx mask = gen_reg_rtx (DImode);
> -  emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 63));
> -  emit_insn (gen_aarch64_simd_bsldf (operands[0], mask,
> -                                  operands[2], operands[1]));
> +  rtx bitmask = gen_reg_rtx (<V_INT_EQUIV>mode);
> +  emit_move_insn (bitmask, GEN_INT (HOST_WIDE_INT_M1U
> +                             << (GET_MODE_BITSIZE (<MODE>mode) - 1)));
> +  emit_insn (gen_copysign<mode>3_insn (operands[0], operands[1], operands[2],
> +                                    bitmask));
>    DONE;
>  }
>  )
>  
> -;; As above, but we must first get to a 64-bit value if we wish to use
> -;; aarch64_simd_bslv2sf.
> -
> -(define_expand "copysignsf3"
> -  [(match_operand:SF 0 "register_operand")
> -   (match_operand:SF 1 "register_operand")
> -   (match_operand:SF 2 "register_operand")]
> +(define_insn "copysign<GPF:mode>3_insn"
> +  [(set (match_operand:GPF 0 "register_operand" "=w,w,w,r")
> +     (unspec:GPF [(match_operand:GPF 1 "register_operand" "w,0,w,r")
> +                  (match_operand:GPF 2 "register_operand" "w,w,0,0")
> +                  (match_operand:<V_INT_EQUIV> 3 "register_operand"
> +                  "0,w,w,X")]
> +      UNSPEC_COPYSIGN))]
>    "TARGET_FLOAT && TARGET_SIMD"
> -{
> -  rtx mask = gen_reg_rtx (DImode);
> -
> -  /* Juggle modes to get us in to a vector mode for BSL.  */
> -  rtx op1 = lowpart_subreg (V2SFmode, operands[1], SFmode);
> -  rtx op2 = lowpart_subreg (V2SFmode, operands[2], SFmode);
> -  rtx tmp = gen_reg_rtx (V2SFmode);
> -  emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 31));
> -  emit_insn (gen_aarch64_simd_bslv2sf (tmp, mask, op2, op1));
> -  emit_move_insn (operands[0], lowpart_subreg (SFmode, tmp, V2SFmode));
> -  DONE;
> -}
> +  "@
> +   bsl\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
> +   bit\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
> +   bif\\t%0.<Vbtype>, %1.<Vbtype>, %3.<Vbtype>
> +   bfxil\\t%<w1>0, %<w1>1, #0, <sizem1>"
> +  [(set_attr "type" "neon_bsl<q>,neon_bsl<q>,neon_bsl<q>,bfm")]
>  )
>  
>  ;; -------------------------------------------------------------------
> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
> index 
> 43be7fd361116d305b0300a814ffca82a9c44a88..4a39e30da13986a6f6ef68eebca7eb29f108b2e9
>  100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -438,7 +438,8 @@
>  (define_mode_attr sizen [(QI "8") (HI "16") (SI "32") (DI "64")])
>  
>  ;; Give the ordinal of the MSB in the mode
> -(define_mode_attr sizem1 [(QI "#7") (HI "#15") (SI "#31") (DI "#63")])
> +(define_mode_attr sizem1 [(QI "#7") (HI "#15") (SI "#31") (DI "#63")
> +                       (HF "#15") (SF "#31") (DF "#63")])
>  
>  ;; Attribute to describe constants acceptable in logical operations
>  (define_mode_attr lconst [(SI "K") (DI "L")])
> @@ -507,7 +508,7 @@
>                         (V8HF "16b") (V2SF  "8b")
>                         (V4SF "16b") (V2DF  "16b")
>                         (DI   "8b")  (DF    "8b")
> -                       (SI   "8b")])
> +                       (SI   "8b")  (SF    "8b")])
>  
>  ;; Define element mode for each vector mode.
>  (define_mode_attr VEL [(V8QI "QI") (V16QI "QI")
> @@ -648,6 +649,9 @@
>  ;; Double vector types for ALLX.
>  (define_mode_attr Vallxd [(QI "8b") (HI "4h") (SI "2s")])
>  
> +;; Mode with floating-point values replaced by like-sized integers.
> +(define_mode_attr V_INT_EQUIV [(DF "DI") (SF "SI")])
> +
>  ;; Mode of result of comparison operations.
>  (define_mode_attr V_cmp_result [(V8QI "V8QI") (V16QI "V16QI")
>                               (V4HI "V4HI") (V8HI  "V8HI")
> diff --git a/gcc/testsuite/gcc.target/aarch64/pr90075.c 
> b/gcc/testsuite/gcc.target/aarch64/pr90075.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..cae7e618fc0cc34646e3e68a419b8de0631e6bda
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/pr90075.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-O1" } */
> +
> +typedef struct {
> +  float one, two;
> +} twofloats;
> +
> +float
> +bug (twofloats tf)
> +{
> +  float f1, f2;
> +  union {
> +    twofloats tfloats;
> +    float arr[2];
> +  } utfloats;
> +
> +  utfloats.tfloats = tf;
> +  f1 = utfloats.arr[1];
> +  f2 = __builtin_copysignf (0, f1);
> +  return f2;
> +}
> 

Reply via email to