This patch exploits native VSX rounding instr, x(v|s)r(d|s)pic, which does rounding using current rounding mode.
According to C standard library document, rint may raise INEXACT exception while nearbyint won't.
Paths
| Differential D72685
[PowerPC] Exploit VSX rounding instrs for rint ClosedPublic Authored by qiucf on Jan 14 2020, 1:28 AM.
Details
Summary This patch exploits native VSX rounding instr, x(v|s)r(d|s)pic, which does rounding using current rounding mode. According to C standard library document, rint may raise INEXACT exception while nearbyint won't.
Diff Detail
Event TimelineComment Actions Unit tests: pass. 61803 tests passed, 0 failed and 781 were skipped. clang-tidy: unknown. clang-format: pass. Build artifacts: diff.json, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml Comment Actions Correct me if I'm wrong. rint(x) returns x if x is an NaN. However, intruction like XSRDPIC may turn SNAN to QNAN. Does it matter? Comment Actions
It sounds like a problem. I don't have an IEEE reference handy, but I'm told POSIX forbids it. I'm sorry I'm not a PowerPC guy, I'm more of a SystemZ guy, so I can't sign off on these changes. The PPCISelLowering.cpp changes look reasonable. Comment Actions
I didn't find the language standard ensuring this (only 'return NaN for NaN'). It seems Glibc's rint would also return a qNaN for sNaN, while some other implementations keeps it. Is that specified by any doc/spec? Thanks. Comment Actions
I found it in man rint on linux, which writes RETURN VALUE These functions return the rounded integer value. If x is integral, +0, -0, NaN, or infinite, x itself is returned. Comment Actions @lkail You can compile this simple program and test. I got following results on Linux with GCC (call for rint): 7FF8000000000000 7FF4000000000000 7FFC000000000000 0 1 0 Comment Actions I believe the conversion of SNaN to QNaN is expected here. Note that the (current) C standard does not mention support signaling NaNs at all, and does not really ever mention them. This is planned to be fixed with the upcoming C2x version, which explicitly states that "rint" is supposed to implement the IEEE-754 "roundToIntegerExact" function. And that function, like most general functions defined by IEEE-754, is indeed defined to return a QNaN when the input is a SNaN. So the current behavior already implements C2x correctly, and is a valid extension to C11, so this should be fine. Comment Actions
Thanks for the information. Since my concern has been resolved, this patch LGTM. Thanks for exploiting these instructions. This revision is now accepted and ready to land.Feb 13 2020, 2:10 AM Closed by commit rG87c773082a8d: [PowerPC] Exploit VSX rounding instrs for rint (authored by qiucf). · Explain WhyFeb 13 2020, 5:12 AM This revision was automatically updated to reflect the committed changes.
Revision Contents
Diff 244396 llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/lib/Target/PowerPC/PPCInstrVSX.td
llvm/test/CodeGen/PowerPC/mi-peephole-splat.ll
llvm/test/CodeGen/PowerPC/scalar-rounding-ops.ll
llvm/test/CodeGen/PowerPC/vector-constrained-fp-intrinsics.ll
llvm/test/CodeGen/PowerPC/vector-rounding-ops.ll
|