mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-31 12:35:51 +00:00
#2839 decides f32 product tininess after rounding, in all four f32 round modes, from the exponents and a UMulHi and IMul of the significands, and builds the flushed value from them. To nearest even, the mode of shaders without a known float mode and of the 0xc0 most titles use, one multiply decides it: one factor times 2^64, which is exact below 2^64, times the other factor rounds the exact product once to 24 bits in the normal range, and 0 < |that| < 2^-62 is tininess after rounding. A product that rounds up to 2^-126 is then not tiny and keeps the emitted product, which is 2^-126 there, so nothing has to be built from the significands. The flush of v_mul_f32 v5, v6, v7 takes 12 IR instructions instead of 34, counted as the instructions the flush select needs beyond the product. vector_constant_factor_tininess pins 12 to nearest and 36 for the directed path of the same instruction, and checks that the directed modes and v_mad_legacy_f32 (before rounding) keep #2839's check. Its round-to-nearest branches are removed as unreachable. The f32 denormals entry says which rounding the check inherits: the multiply is a plain OpFMul like the product, with no f32 rounding mode requested, so it relies on the driver rounding f32 to nearest even, as the products do. F32ConstantFactorTininess names the row a check before rounding flushes, 0x3f7ffffe * 0x00800001, which keeps the emitted 0x00800000. Against #2839 to nearest even, a model of both checks agrees on 1,074,977,546 operand pairs (every 24-bit significand at both rounding thresholds, random pairs, specials) with each other and with an exact reference. On an RTX 5070 the outputs of #2839's own tininess and mixed-source shaders are bit-identical with either lowering over 165,298 and 164,008 generated rows in all six float modes tested. Co-Authored-By: Claude Opus 5.5 <[email protected]>