<div dir="ltr"><div dir="ltr">On Fri, Nov 9, 2018 at 1:57 PM Thomas Lively <<a href="mailto:tlively@google.com">tlively@google.com</a>> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">I would agree, but the expansion also has to properly treat negative zero as less than zero, </div></blockquote><div><br></div><div>I don't think libm does this. I'm also under the impression that IEEE-754 doesn't specify this either. Could you point me to the clause that does specify it?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">which leads to something like the following:<div><br></div><div>;; Find minimum if both zero</div><div>%a_sign = fgetsign %a</div><div>%b_sign = fgetsign %b</div><div>%a_is_lesser_zero = icmp ugt %a_sign, %b_sign</div><div>%minimum_zeros = select %a_is_lesser_zero, %a, %b</div><div><br></div><div>;; Find minimum if not both zero (from above)</div><div>%no_nan_and_a_lesser = fcmp olt %a, %b</div><div>%lesser_or_b_if_nan = select %no_nan_and_a_lesser, %a, %b</div><div>%a_not_nan = fcmp ord %a, %a</div><div>%minimum_not_zeros = select %a_not_nan, %lesser_or_b_if_nan, %a</div><div><br></div><div>;; Choose between zeros and not-zeros</div><div><div>%a_is_zero = fcmp oeq %a, 0</div><div>%b_is_zero = fcmp oeq %b, 0</div><div>%both_zero = and %a_is_zero, %b_is_zero</div></div><div>%minimum = select %both_zero, %minimum_zeros, %minimum_not_zeros</div><div><br></div><div>Which is considerably less reasonable.</div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Nov 9, 2018 at 7:00 AM Cameron McInally via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">On Thu, Nov 8, 2018 at 11:35 PM Fabian Giesen via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">What is so complicated about these? Shouldn't they just correspond to <br>
two compares + selects?<br>
<br>
To give a concrete example, x86 MIN[SP][SD] and MAX[SP][SD], <br>
respectively, correspond exactly to<br>
<br>
MIN*: select(a < b, a, b) (i.e. "a < b ? a : b")<br>
MAX*: select(a > b, a, b) (i.e. "a > b ? a : b")<br>
<br>
IIRC, MINIMUM and MAXIMUM have the added requirement that they should <br>
return NaN if _either_ input is NaN, whereas the above will return NaN <br>
if the second input (i.e. b) is NaN, but not if the first is.<br>
<br>
So we need to explicitly catch the case where a is NaN as well. For <br>
minimum, that works out to something like:<br>
<br>
%3 = fcmp olt float %a, %b<br>
%4 = select i1 %3, float %a, float %b ; (a < b) ? a : b<br>
%5 = fcmp ord float %a, %a ; true if !isNaN(a)<br>
%6 = select i1 %5, float %4, float %a ; if a was NaN, return a<br>
<br>
for the entire operation. The logic here is that if isNaN(a) || <br>
isNaN(b), the initial comparison will evaluate to false and %4 ends up <br>
being b. If isNaN(b), this is a NaN value (as required). The case we are <br>
missing is when isNaN(a) && !isNaN(b), where %4 is not a NaN; the second <br>
compare + select fixes that one up.<br>
<br>
The first pair of these corresponds to a single (x86-style) MIN/MAX, and <br>
the second turns into a compare followed by (depending on target <br>
instruction set) either a BLEND or some logic ops.<br>
<br>
For minimumNumber/maximumNumber, you should be able to use a similar <br>
construction. Showing the example for minimumNumber here:<br>
<br>
%3 = fcmp olt float %a, %b<br>
%4 = select i1 %3, float %a, float %b ; (a < b) ? a : b<br>
%5 = fcmp ord float %b, %b ; true if !isNaN(b)<br>
%6 = select i1 %5, float %4, float %a ; if b was NaN, return a<br>
<br>
Starts out the same as before. Here, the tricky case is !isNaN(a) && <br>
isNaN(b). The initial select %4 will result in the (NaN) b in that case, <br>
and the second compare/select pair switches the result to a instead; we <br>
will only get a NaN result if both inputs were NaN.<br>
<br>
I might be missing something here, but that seems like a fairly harmless <br>
expansion, as such things go, and going to compiler-rt feels like overkill.<br></blockquote><div><br></div><div>+1 </div></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi-2Dbin_mailman_listinfo_llvm-2Ddev&d=DwMFaQ&c=slrrB7dE8n7gBJbeO0g-IQ&r=O_4M49EtSpZ_-BQYeigzGv0P4__noMcSu2RYEjS1vKs&m=z5knBS-gNPEpc4ggdvRihjkzXuNMBoct19biXn7wwik&s=1cTiDQsdNprlvfeQYApN9ha9XRIuGNHANCtF2RvbWPk&e=" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>
</blockquote></div></div></div>