From 2c24e0568392e51a77ebdaab629d631969ce8966 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Thu, 8 Aug 2024 18:51:30 +0100 Subject: [PATCH] AArch64: Fix signbit mask creation after late combine [PR116229] 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 thus producing incorrect code. This change adds a new unspec FNEG on DI mode which prevents this simplication. gcc/ChangeLog: PR target/116229 * config/aarch64/aarch64-simd.md (aarch64_fnegv2di2): 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. --- gcc/config/aarch64/aarch64-simd.md | 9 +++++++++ gcc/config/aarch64/aarch64.cc | 4 ++-- gcc/config/aarch64/iterators.md | 1 + gcc/testsuite/gcc.target/aarch64/pr116229.c | 20 ++++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/pr116229.c diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 816f499e963..cc612ec2ca0 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -2629,6 +2629,15 @@ [(set_attr "type" "neon_fp_neg_")] ) +(define_insn "aarch64_fnegv2di2" + [(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 "abs2" [(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 2ac5a22c848..bfd7bcdef7c 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -11808,8 +11808,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 aaa4afefe2c..20a318e023b 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -689,6 +689,7 @@ 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 00000000000..cc42078478f --- /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(); +}