This is a partial port of the code used by the SelectionDAGBuilder to translate selects.
In particular, see matchSelectPattern in ValueTracking.cpp. This is a GISel-equivalent of the portion which handles fminnum/fmaxnum/fminimum/fmaximum.
I tried to set it up so it'd be easy to add the non-FP cases. Those are simpler. On the AArch64-end, it seems like the FP cases are more important for perf right now, so I bit the bullet and went at the more complicated problem. :)
I elected to do this as a post-legalize combine rather than in the IRTranslator because
- Deciding which fmax/fmin to use can depend on legalization rules
- Philosophically-speaking (TM), putting it in a combine just feels cleaner
- Being able to enable/disable the combine is handy
Another option would be to use the ValueTracking code in the IRTranslator and match what SelectionDAGBuilder::visitSelect does. I think that may be somewhat annoying since we'd need to write lowerings back into the selects in the legalizer. I'm not strongly opposed to the approach.
We'd also want to be careful with vector selects once that's implemented, which explicitly check if a vector select is legal on the target. That'd probably need a hook.
From what I can tell, doing this as a combine is probably a cleaner option long-term.
I prefer enum class for new code, but it is up to you.