Re: [PATCH] alpha: round to odd before narrowing TFmode to SFmode
Jeffrey Law <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
On 8/9/2026 1:12 PM, Matt Turner wrote: > Alpha has no instruction converting TFmode to SFmode, so trunctfsf2 goes > through DFmode and has to avoid rounding twice. > > It tried to, by setting a sticky bit at fraction bit 48 when the low word > of the TFmode value was nonzero: a DFmode value with that bit set cannot > sit exactly halfway between two SFmode values, leaving the second > rounding nothing to break a tie on. But the bit is set before the > conversion to DFmode, and the carry out of the bits that conversion > discards can propagate up through bit 48 and clear it, landing on the > halfway value it was there to avoid. > > Round to odd at the last fraction bit DFmode keeps instead. The value is > then exactly representable in DFmode, so that conversion does not round > and the one to SFmode is the only rounding. > > Over values constructed around SFmode halfway points the old sequence is > wrong for about a quarter of them and the new one for none. Uniformly > random values do not reach it: that needs the conversion to DFmode to > carry all the way to a halfway value. > > Rounding twice also loses the underflow flag when the result is subnormal. > glibc's narrowing functions compute a round-to-odd value in the wider type > and convert it once, and that single conversion is what is meant to raise > underflow; splitting it in two can leave the intermediate DFmode value > exactly representable in SFmode, so the final step raises nothing. > > Found through glibc's math testsuite, where three of the narrowing fma > tests returned a wrong result. Retested there on an EV67 with a glibc > built by a compiler carrying this patch: the wrong results are gone, every > test now reporting a maximum error of 0 ulp, and the six narrowing add and > subtract tests that had been failing on the lost underflow flag pass. The > narrowing tests that still fail there do so for an unrelated reason, Alpha > determining tininess from the delivered result rather than as IEEE 754 > describes, which no change to the compiler can address. > --- > gcc/config/alpha/alpha.md | 23 +++++++++++------ > gcc/testsuite/gcc.target/alpha/trunctfsf2-1.c | 25 +++++++++++++++++++ > 2 files changed, 40 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/alpha/trunctfsf2-1.c THanks. I constructed a ChangeLog entry and pushed this to the trunk. Not sure how much time you have Matt, but these tests started failing about a month ago on alpha-linux-gnu. No idea why yet. Tests that now fail, but worked before (28 tests): gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O0 execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O0 execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O1 execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O1 execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O2 execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O2 execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O3 -g execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -O3 -g execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -Os execution test gcc: gcc.dg/torture/fp-int-convert-float32-timode.c -Os execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O0 execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O0 execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O1 execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O1 execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O2 execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O2 execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O3 -g execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -O3 -g execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -Os execution test gcc: gcc.dg/torture/fp-int-convert-timode.c -Os execution test 31d967232a9331ad72571da27550b2f5d7d38523 was the last good hash. f06e56614b948ad88dabf63020f47713b7dea0ec was the first reported bad hash if you're going to try and chase it down. Jeff