https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814

            Bug ID: 111814
           Summary: on sh4, __builtin_nan* returns signalling NaNs instead
                    of quiet NaNs and vice versa
           Product: gcc
           Version: 11.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bruno at clisp dot org
  Target Milestone: ---

Created attachment 56109
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56109&action=edit
test case for float

The bit that distinguishes a quiet NaN from a signalling NaN is,
according to <https://en.wikipedia.org/wiki/NaN#Encoding>, the most
significant bit of the mantissa field.  This bit is
*  == 0 to indicate a quiet NaN or Infinity,
   == 1 to indicate a signalling NaN,
   on these CPUs: hppa, mips, sh4.
*  == 1 to indicate a quiet NaN,
   == 0 to indicate a signalling NaN or Infinity,
   on all other CPUs.

The statement regarding sh4 follows from the "SH-4 Software Manual"
<https://www.renesas.com/us/en/document/mas/sh-4-software-manual>
page 143.

The GCC primitives __builtin_nan* get this wrong:
- __builtin_nanf, __builtin_nan, __builtin_nanl return a signalling
  NaN instead of a quiet NaN.
- __builtin_nansf, __builtin_nans, __builtin_nansl return a quiet
  NaN instead of a signalling NaN.

How to reproduce:

Compile and run the attached programs in the Linux/sh4 QEMU user-mode
environment. I use QEMU version 8.0.2.

$ sh4-linux-gnu-gcc-11 foof.c
$ ./a.out 
Bits: 32
Mantissa bits: 24
Min exponent: -125
Max exponent:  128
1.0 representation:         00 00 80 3F
1/3 representation:         AB AA AA 3E
+Infinity representation:   00 00 80 7F
-Infinity representation:   00 00 80 FF
qNaN representation:        FF FF BF 7F
gcc qNaN representation:    00 00 C0 7F
gcc sNaN representation:    00 00 A0 7F

$ sh4-linux-gnu-gcc-11 food.c
$ ./a.out 
Bits: 64
Mantissa bits: 53
Min exponent: -1021
Max exponent:  1024
1.0 representation:         00 00 00 00 00 00 F0 3F
1/3 representation:         55 55 55 55 55 55 D5 3F
+Infinity representation:   00 00 00 00 00 00 F0 7F
-Infinity representation:   00 00 00 00 00 00 F0 FF
qNaN representation:        FF FF FF FF FF FF F7 7F
gcc qNaN representation:    00 00 00 00 00 00 F8 7F
gcc sNaN representation:    00 00 00 00 00 00 F4 7F

$ sh4-linux-gnu-gcc-11 fool.c
$ ./a.out 
Bits: 64
Mantissa bits: 53
Min exponent: -1021
Max exponent:  1024
1.0 representation:         00 00 00 00 00 00 F0 3F
1/3 representation:         55 55 55 55 55 55 D5 3F
+Infinity representation:   00 00 00 00 00 00 F0 7F
-Infinity representation:   00 00 00 00 00 00 F0 FF
qNaN representation:        FF FF FF FF FF FF F7 7F
gcc qNaN representation:    00 00 00 00 00 00 F8 7F
gcc sNaN representation:    00 00 00 00 00 00 F4 7F

The row "qNaN representation" shows the value of 0.0 / 0.0, as computed
by QEMU. As you can see, it is consistent with the "SH-4 Software Manual"
<https://www.renesas.com/us/en/document/mas/sh-4-software-manual>
page 143.

The values in the rows "gcc qNaN representation" and
"gcc sNaN representation" are wrong: The most significant bit
of the mantissa field (bit 22 or 51, respectively) is the opposite
of what it should be.

Reply via email to