| > Floating-point operations are stateful in any CPU made during the last 40 years. But sane programming languages entirely hide that (to the same extent that they hide integer flags and registers in general), at the very least by default; and in such sane languages, programmers do not need to be aware of any of this mess. e.g. C's requirement of "#pragma STDC FENV_ACCESS ON" for non-default FP status, and lack thereof in 99.99% of code; C spec even explicitly notes: > With these conventions, a programmer can safely assume default floating-point control modes (or be unaware of them). The responsibilities associated with accessing the floating-point environment fall on the programmer or program that does so explicitly. (never mind basically every other language, which don't even allow anything other than round-nearest-ties-even + no-exceptions) > Enabling some or all kinds of FP exceptions has absolutely no influence on auto-vectorization. It also has no influence on speed, in well-designed CPUs. If you want to have deterministic semantics (i.e. want to be a sane language), it absolutely does; it means that, in `a+b; x[i];`, the `x[i]` load must not happen if `a+b` results in a trap. So you cannot ever execute the next loop iteration before being sure the previous doesn't trap. Entirely forbidding autovectorization. If you want to still have autovectorization, you'd need to have some washy semantics of like "the trap of an fp op can be delayed to an arbitrarily-later point in time, up to [insert some messy ambiguous incomplete attempt at establishing some limit to this]", which, besides making basic code non-deterministic (yikes! we don't need more of that in the world), will make proving compiler optimization correctness extra-messy. Non-trapping exceptions (i.e. accruing) would be simpler to preserve through vectorization (allowing reordering up to reading the status, which is explicit in code), but you're back to allowing observable NaNs and making programmers insert manual checks. (and even then, you'd run into issues if you wanted to vectorize the tail of a loop on architectures without maskable FP SIMD ops) (and, of course, unrelated to any of this, giving the programmer control over FP status means compilers are massively-restricted on optimizing code - can't DCE float ops, can't insert new FP ops even if it would be beneficial, etc) |