During testing, I found that when using __double2int_rn (as well as __double2uint_rn, __double2ull_rn, and __double2ll_rn), the rounding result when passing a runtime variable is inconsistent with the result when passing a compile-time constant directly.
This appears to be caused by a precision issue in the compiler’s constant folding behavior.
Problem Description: The input double-precision floating-point value I tested is 5.00000000000000111e-01, which is strictly greater than 0.5 (essentially 0.5 + epsilon). According to the Round-to-Nearest-Even (RNE) rounding mode, this value should be rounded to 1.
-
When passing this value via a runtime argument (loaded from memory via a pointer), the underlying GPU executes the correct hardware instruction (e.g.,
cvt.rni.s32.f64) and correctly evaluates the result to1. -
When passing this value directly as a compile-time constant (literal), the
nvcccompiler folds it to0at compile time. It is highly likely that it loses the extremely small trailing precision when parsing the literal, treating it exactly as an absolute0.5(and thus rounding it to0according to the round-to-even rule).
Compiler Explorer Example: Compiler Explorer
Question: Could the official team confirm if this is a known bug in nvcc regarding precision loss during host-side constant folding when handling the _rn rounding family of intrinsics?