[GlobalISel] Combine select + fcmp to fminnum/fmaxnum/fminimum/fmaximum
authorJessica Paquette <jpaquette@apple.com>
Fri, 16 Sep 2022 20:32:42 +0000 (13:32 -0700)
committerJessica Paquette <jpaquette@apple.com>
Fri, 16 Sep 2022 20:35:46 +0000 (13:35 -0700)
commit1076b31da8da8854e1dfca8f1a9a03de9fd4f8f5
tree3af8e8ef1a15d066ee2ab9dcb5166d4a8bc56481
parent59365f33e27b24b6ecc971c53889c8ac3b34b15d
[GlobalISel] Combine select + fcmp to fminnum/fmaxnum/fminimum/fmaximum

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.

Differential Revision: https://reviews.llvm.org/D116702
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/lib/Target/AArch64/AArch64Combine.td