On 12/28/23 22:56, Li, Pan2 wrote:
Thanks Jeff.

I think I locate where aarch64 performs the trick here.

1. In the .final we have rtl like

(insn:TI 6 8 29 (set (reg:SF 32 v0)
         (const_double:SF -0.0 [-0x0.0p+0])) 
"/home/box/panli/gnu-toolchain/gcc/gcc/testsuite/gcc.dg/pr30957-1.c":31:7 79 
{*movsf_aarch64}
      (nil))

2. the movsf_aarch64 comes from the aarch64.md file similar to the below rtl. 
Aka, it will generate movi\t%0.2s, #0 if
the aarch64_reg_or_fp_zero is true.

1640 (define_insn "*mov<mode>_aarch64"
1641   [(set (match_operand:SFD 0 "nonimmediate_operand")
1642       match_operand:SFD 1 "general_operand"))]
1643   "TARGET_FLOAT && (register_operand (operands[0], <MODE>mode)
1644     || aarch64_reg_or_fp_zero (operands[1], <MODE>mode))"
1645   {@ [ cons: =0 , 1   ; attrs: type , arch  ]
1646      [ w        , Y   ; neon_move   , simd  ] movi\t%0.2s, #0

3. Then we will have aarch64_float_const_zero_rtx_p here, and the -0.0 input 
rtl will return true in line 10873 because of no-signed-zero is given.

10863 bool
10864 aarch64_float_const_zero_rtx_p (rtx x
10865 {
10866   /* 0.0 in Decimal Floating Point cannot be represented by #0 or
10867      zr as our callers expect, so no need to check the actual
10868      value if X is of Decimal Floating Point type.  */
10869   if (GET_MODE_CLASS (GET_MODE (x)) == MODE_DECIMAL_FLOAT)
10870     return false;
10871
10872   if (REAL_VALUE_MINUS_ZERO (*CONST_DOUBLE_REAL_VALUE (x)))
10873     return !HONOR_SIGNED_ZEROS (GET_MODE (x));
10874   return real_equal (CONST_DOUBLE_REAL_VALUE (x), &dconst0);
10875 }

I think that explain why we have +0.0 in aarch64 here.
Yup. Thanks a ton for diving into this. So I think that points us to the right fix, specifically we should be turning -0.0 into 0.0 when !HONOR_SIGNED_ZEROS rather than xfailing the test.

I think we'd need to adjust reg_or_0_operand and riscv_output_move, probably the G constraint as well. We might also need to adjust move_operand and perhaps riscv_legitimize_move.

jeff

Reply via email to