[llvm-dev] Proposed new min and max intrinsics

Cameron McInally via llvm-dev llvm-dev at lists.llvm.org
Fri Nov 9 07:00:18 PST 2018


On Thu, Nov 8, 2018 at 11:35 PM Fabian Giesen via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> What is so complicated about these? Shouldn't they just correspond to
> two compares + selects?
>
> To give a concrete example, x86 MIN[SP][SD] and MAX[SP][SD],
> respectively, correspond exactly to
>
>    MIN*: select(a < b, a, b) (i.e. "a < b ? a : b")
>    MAX*: select(a > b, a, b) (i.e. "a > b ? a : b")
>
> IIRC, MINIMUM and MAXIMUM have the added requirement that they should
> return NaN if _either_ input is NaN, whereas the above will return NaN
> if the second input (i.e. b) is NaN, but not if the first is.
>
> So we need to explicitly catch the case where a is NaN as well. For
> minimum, that works out to something like:
>
>    %3 = fcmp olt float %a, %b
>    %4 = select i1 %3, float %a, float %b ; (a < b) ? a : b
>    %5 = fcmp ord float %a, %a ; true if !isNaN(a)
>    %6 = select i1 %5, float %4, float %a ; if a was NaN, return a
>
> for the entire operation. The logic here is that if isNaN(a) ||
> isNaN(b), the initial comparison will evaluate to false and %4 ends up
> being b. If isNaN(b), this is a NaN value (as required). The case we are
> missing is when isNaN(a) && !isNaN(b), where %4 is not a NaN; the second
> compare + select fixes that one up.
>
> The first pair of these corresponds to a single (x86-style) MIN/MAX, and
> the second turns into a compare followed by (depending on target
> instruction set) either a BLEND or some logic ops.
>
> For minimumNumber/maximumNumber, you should be able to use a similar
> construction. Showing the example for minimumNumber here:
>
>    %3 = fcmp olt float %a, %b
>    %4 = select i1 %3, float %a, float %b ; (a < b) ? a : b
>    %5 = fcmp ord float %b, %b ; true if !isNaN(b)
>    %6 = select i1 %5, float %4, float %a ; if b was NaN, return a
>
> Starts out the same as before. Here, the tricky case is !isNaN(a) &&
> isNaN(b). The initial select %4 will result in the (NaN) b in that case,
> and the second compare/select pair switches the result to a instead; we
> will only get a NaN result if both inputs were NaN.
>
> I might be missing something here, but that seems like a fairly harmless
> expansion, as such things go, and going to compiler-rt feels like overkill.
>

+1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20181109/3bf0c105/attachment.html>


More information about the llvm-dev mailing list