Tamar Christina <tamar.christ...@arm.com> writes: > Hi All, > > The optimization to generate a DI signbit constant by using fneg was relying > on nothing being able to push the constant into the negate. It's run quite > late for this reason. > > However late combine now runs after it and triggers RTL simplification based > on > the neg. When -fno-signed-zeros this ends up dropping the - from the -0.0 and > this producing incorrect code. > > This change adds a new unspec FNEG on DI mode which prevents this > simplication.
Yeah, agreed that that's the most robust fix. > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. > > Ok for master? > > Thanks, > Tamar > > gcc/ChangeLog: > > PR target/116229 > * config/aarch64/aarch64-simd.md (aarch64_fnegv2di2<vczle><vczbe>): New. > * config/aarch64/aarch64.cc (aarch64_maybe_generate_simd_constant): > Update call to gen_aarch64_fnegv2di2. > * config/aarch64/iterators.md: New UNSPEC_FNEG. > > gcc/testsuite/ChangeLog: > > PR target/116229 > * gcc.target/aarch64/pr116229.c: New test. LGTM. OK if there are no objections in 24 hours. Thanks, Richard > > --- > > diff --git a/gcc/config/aarch64/aarch64-simd.md > b/gcc/config/aarch64/aarch64-simd.md > index > 459e11b09a19cdc97a5153cfd8c4e0e07a7ffb0c..75b2d6cf3ea0902cfe89c2f54a7e60e041fba536 > 100644 > --- a/gcc/config/aarch64/aarch64-simd.md > +++ b/gcc/config/aarch64/aarch64-simd.md > @@ -2629,6 +2629,15 @@ (define_insn "neg<mode>2<vczle><vczbe>" > [(set_attr "type" "neon_fp_neg_<stype><q>")] > ) > > +(define_insn "aarch64_fnegv2di2<vczle><vczbe>" > + [(set (match_operand:V2DI 0 "register_operand" "=w") > + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")] > + UNSPEC_FNEG))] > + "TARGET_SIMD" > + "fneg\\t%0.2d, %1.2d" > + [(set_attr "type" "neon_fp_neg_d")] > +) > + > (define_insn "abs<mode>2<vczle><vczbe>" > [(set (match_operand:VHSDF 0 "register_operand" "=w") > (abs:VHSDF (match_operand:VHSDF 1 "register_operand" "w")))] > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index > 9810f2c039004cae4df37d07b5dcac948745011a..04fa4e71ae1ed2047f304a7a0e9607c7dc790652 > 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -11804,8 +11804,8 @@ aarch64_maybe_generate_simd_constant (rtx target, rtx > val, machine_mode mode) > /* Use the same base type as aarch64_gen_shareable_zero. */ > rtx zero = CONST0_RTX (V4SImode); > emit_move_insn (lowpart_subreg (V4SImode, target, mode), zero); > - rtx neg = lowpart_subreg (V2DFmode, target, mode); > - emit_insn (gen_negv2df2 (neg, copy_rtx (neg))); > + rtx neg = lowpart_subreg (V2DImode, target, mode); > + emit_insn (gen_aarch64_fnegv2di2 (neg, copy_rtx (neg))); > return true; > } > > diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md > index > 95fe8f070f4c3f5770e4424162bf13b712adedf3..92bebcf48b1e4462537e8ca2b97df46de5e73cb5 > 100644 > --- a/gcc/config/aarch64/iterators.md > +++ b/gcc/config/aarch64/iterators.md > @@ -686,6 +686,7 @@ (define_c_enum "unspec" > UNSPEC_FMINNMV ; Used in aarch64-simd.md. > UNSPEC_FMINV ; Used in aarch64-simd.md. > UNSPEC_FADDV ; Used in aarch64-simd.md. > + UNSPEC_FNEG ; Used in aarch64-simd.md. > UNSPEC_ADDV ; Used in aarch64-simd.md. > UNSPEC_SMAXV ; Used in aarch64-simd.md. > UNSPEC_SMINV ; Used in aarch64-simd.md. > diff --git a/gcc/testsuite/gcc.target/aarch64/pr116229.c > b/gcc/testsuite/gcc.target/aarch64/pr116229.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..cc42078478f77b3ee96de3e7fe853088d0c57c1c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/pr116229.c > @@ -0,0 +1,20 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 -fno-signed-zeros" } */ > + > +typedef __attribute__((__vector_size__ (8))) unsigned long V; > + > +V __attribute__((__noipa__)) > +foo (void) > +{ > + return (V){ 0x8000000000000000 }; > +} > + > +V ref = (V){ 0x8000000000000000 }; > + > +int > +main () > +{ > + V v = foo (); > + if (v[0] != ref[0]) > + __builtin_abort(); > +}