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