It turns out that the behaviour of these intrinsics is different enough from generic IR that this will cause problems, INF/NAN/out of range values are guaranteed to result in a 0x80000000 value - which plays havoc with constant folding which converts them to either zero or UNDEF. This is also an issue with the scalar implementations (which were already generic IR and what I was trying to match).

This patch changes both scalar and packed versions back to using x86-specific builtins.

It also deals with the other scalar conversion cases that are runtime rounding mode dependent and can have similar issues with constant folding.

I was being possibly over thorough - there is scope for some very careful constant folding.

The cvt versions rely on the runtime rounding mode, so constant folding may not match the same result (we could maybe just permit exact conversions?).

The cvtt versions should work but its not what I saw in some basic tests on godbolt with large values such as FLT_MAX. I'll see if we can improve the existing tests to see what is going on and make a decision on what we can safely support.

Hmm... for the rounding mode, I think we generally take the position that we don't support changing it. I mean, if we did allow that, we couldn't implement addps on top of the LLVM IR fadd. (We might have to revisit this once LLVM gets proper support for rounding modes.)