What compilers are you using, what flags are you using with those compilers?
If you care about it, you need to use the appropriate flags to get a strict floating-point model. If you merely have a precise or fast floating-point model, calling fetestexception is going to result in unspecified behavior.
[If you really want to be strict, the result of flags are unspecified if you don't use #pragma FENV_ACCESS ON, but gcc refuses to support FENV_ACCESS pragma, and you instead need to use command-line flags to get the same effect.]
> I think I have an outdated idea that there should be a way to have the exception trigger a SIGFPE, and that modern processors don't do that.
On Intel, you can clear the exception mask for the INVALID FP exception in mxcsr and get an SIGFPE whenever an operation raises INVALID [assuming, again, strict model to ensure the optimizer respects fp exceptions.] I don't know how, or if, AArch64 can enable hardware traps on floating-point exceptions.
You need to enable floating point trapping. It's trivial, but it's not on by default.
Although, in that case, this function would still be pure as far as Haskell is concerned. Because its output only depends on its input. Interrupts/exceptions are outside of the scope of the type system as far as an individual function goes.
I think I have an outdated idea that there should be a way to have the exception trigger a SIGFPE, and that modern processors don't do that.