The default promotion for the add_sat/sub_sat nodes currently does:
// 1. ANY_EXTEND iN to iM // 2. SHL by M-N // 3. [US][ADD|SUB]SAT // 4. L/ASHR by M-N
If the promoted add_sat or sub_sat node is not legal, this can produce code that effectively does a lot of shifting (and requiring large constants to be materialised) just to use the overflow flag. It is simpler to just do the saturation manually, using the higher bitwidth addition and a min/max against the saturating bounds. That is what this patch attempts to do.
A few points of interest:
- This still uses the existing promotion when the promoted add/sub_sat is legal. In many situations (but not all) it would probably be better to just perform the new promotion.
- It always creates a MIN and MAX node, even if they are not legal. The alternative would be to be to create a cmp/select pair, which these will legalise into anyway.
- We only have AArch64 and X86 tests. I have added ARM (for which just the differences are shown here). I'm happy to add other architectures if people are interested.