On Thu, 2023-11-23 at 18:03 +0000, Joseph Myers wrote:
> The rint functions indeed don't set errno (don't have domain or range 
> errors, at least if you ignore the option for signaling NaNs arguments to 
> be domain errors - which is in TS 18661-1, but not what glibc does, and 
> not in C23).
> 
> The lrint / llrint functions should logically set errno for a domain error 
> in the cases where they raise "invalid".  That they don't in glibc is 
> glibc bug 6798.  And __builtin_irint functions can fall back to calling 
> lrint functions if not expanded inline.  So the potential for errno 
> setting explains why -fno-math-errno is required.

I agree.  But this is not preventing optimizing vectorized "(int)
rintf(x[i])" into a vftint.w.s instruction which does not set errno.

> I don't see an obvious need for -funsafe-math-optimizations here - but at 
> least -fno-trapping-math should be needed in some cases.  That's because 
> rint raises "inexact" for noninteger argument - but lrint doesn't raise 
> "inexact" when raising "invalid".  So if, for example, long is 32-bit and 
> the floating type in use is double, calling rint for a noninteger argument 
> too large for long, and then converting to a 32-bit signed integer type 
> (long or int), raises both "inexact" and "invalid" - but a direct call to 
> lrint raises such "invalid".

Interesting...  But for (i32)rintf(x) it's impossible to have a non-
integer value out of [-2147483648, 2147483648) except NaN and +-Inf,
likewise for (i64)rint(x).  So using vftint.w.s and vftint.l.d
instructions should still be fine.  We also have a vftint.w.d
instruction but it's only used as an intrinsic as at now, and my patch
does not attempt to use it.

Lulu: so my conclusion is an (i32)rintf -> irintf transformation is
indeed "unsafe" generally, but a machine-specific transformation to
vftint.w.s is fine and we should use the define_insn to do it.  Do you
agree?

-- 
Xi Ruoyao <xry...@xry111.site>
School of Aerospace Science and Technology, Xidian University

Reply via email to