[InstCombine] Don't convert a compare+select into a minnum/maxnum intrinsic that can't be lowered back to a compare+select (#177821)

This is a step on the yak-shaving expedition to properly implement the
new `minnum`/`maxnum` signed-zero semantics.

`InstCombineSelect` will convert a `fcmp`+`select` sequence to a
`minnum`/`maxnum` intrinsic. It doesn't require the `fcmp` to have any
particular fast-math flags, just that the `select` has `nnan` and `nsz`
(or is being used in a context where the result doesn't care about
signed zero).

It's not correct to propagate the `nnan` flag from the `fcmp`
instruction for poison-propagation reasons. Patches like
https://github.com/llvm/llvm-project/pull/117977 and
https://github.com/llvm/llvm-project/pull/141010 have *generously* made
it so that if `fcmp` doesn't have fast-math flags, we can still perform
the transformation by simply dropping the flags on the generated
intrinsic.

Unfortunately, converting an `fcmp`+`select` with fast-math flags, to a
`minnum`/`maxnum` without fast-math flags, is actually a
*pessimization*. Common ISAs like x86 and WebAssembly do not provide
single floating-point minimum/maximum instructions that handle NaN in
the same way as `minnum`/`maxnum`. They have to fall back to a routine
or a libcall, which causes its own problems
(https://github.com/llvm/llvm-project/issues/54554).

[Here's an example](https://llvm.godbolt.org/z/avYxa7ccK). Using just
`llc`, the function compiles to a single `maxss`. But with `clang -O3`,
which enables InstCombine optimizations, we end up with a much larger
(and completely unnecessary) routine for handling NaNs.

We should only perform this transformation if it's safe to add `nnan`
and `nsz` to the `minnum`/`maxnum` call, since those are the flags
necessary for lowering it *back* into an `fcmp`+`select` (or equivalent
code).

There's currently one case where we might end up without `nsz` on the
intrinsic call: if the output has one use, and that use doesn't care
about signed zero. To account for that, we should also unconditionally
set `nsz` on the generated intrinsic call.

With this in place, it should be safe to eventually revert
https://reviews.llvm.org/D122610 and further consolidate
`minnum`/`maxnum` handling.

GitOrigin-RevId: 9b3b64310650654d063ce7816c860f67bfbadd38
6 files changed