<div dir="ltr"><div>Actually it is hard to rely on default FP environment in many cases. We know that a program starts with default FP state installed. But in other cases we generally cannot assume this. For example, can we assume default FP environment in this case?<br><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>float qqq(float x) {</div><div> return nearbyint(x);</div><div>}</div></blockquote><div><br>Depending on the answer compiler either generates non-constrained intrinsic or constrained. Result of `nearbyint` depends on current rounding mode, so this function accesses FP environment - it implicitly reads rounding mode. Shall user use `#pragma STDC FENV_ACCESS on` here? Actually no.<br><br>C standard (n2454):<br><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>7.6.1p2</div><div>The FENV_ACCESS pragma provides a means to inform the implementation when a program might</div><div>access the floating-point environment to test floating-point status flags or run under non-default</div><div>floating-point control modes.</div><div><br></div><div>7.6p1</div><div>A floating-point status flag is a</div><div>system variable whose value is set (but never cleared) when a floating-point exception is raised, which</div><div>occurs as a side effect of exceptional floating-point arithmetic to provide auxiliary information.</div></blockquote><div><br>Not every access to FP environment requires `#pragma STDC FENV_ACCESS on`, only that which reads FP exception status or sets control modes. None occurs in the example above.<br><br>So, even if `#pragma STDC FENV_ACCESS on` is absent we should not assume default FP environment in the case of functions that read control modes, including nearbyint and rint. They cannot assume default rounding mode and must be ordered relative to other instructions that may access FP environment. The scope of non-constrained intrinsics would be only initialization code, which seems to be marginal case.<br></div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Thanks,<br>--Serge<br></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Mar 4, 2020 at 12:59 AM Serge Pavlov <<a href="mailto:sepavloff@gmail.com">sepavloff@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">One concern with replacing llvm.rint and llvm.nearbyint with llvm.roundeven makes it difficult to turn back into a libcall if the backend doesn't have an instruction for it. You can't just call the roundeven library function since that wouldn't exist in older libm implementations. So ideally you would know which function was originally used in the user code and call that.</blockquote><div><br></div><div>Yes, you are right. Such optimization at IR level probably does not make sense.</div><br clear="all"><div><div dir="ltr">Thanks,<br>--Serge<br></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Mar 3, 2020 at 11:41 PM Craig Topper <<a href="mailto:craig.topper@gmail.com" target="_blank">craig.topper@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Note, EVEX static rounding forces suppress all exceptions. You can't have static rounding with exceptions.</div><div dir="ltr"><br></div><div>We're also talking about making the vector predicated floating point intrinsics that Simon Moll is working on support both strict and non-strict using operand bundles. So you're right we could probably merge constrained and non-constrained versions of the existing intrinsics.</div><div><br></div><div>One concern with replacing llvm.rint and llvm.nearbyint with llvm.roundeven makes it difficult to turn back into a libcall if the backend doesn't have an instruction for it. You can't just call the roundeven library function since that wouldn't exist in older libm implementations. So ideally you would know which function was originally used in the user code and call that.</div><div dir="ltr"><br clear="all"><div><div dir="ltr">~Craig</div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Mar 3, 2020 at 8:23 AM Serge Pavlov 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:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The only issue I see is that since we also assume FP operations have no side effects by default there is no difference between llvm.rint and llvm.nearbyint. I wouldn’t have a problem with dropping llvm.rint completely.</blockquote><div><br></div>The forthcoming C standard (<a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2454.pdf" target="_blank">http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2454.pdf</a>, 7.12.9.8) defines new function, `roundeven`, which implements IEEE-754 operation `roundToIntegralTiesToEven`. When corresponding intrinsic will be implemented (I am working on such patch), llvm.rint and llvm.nearbyint will identical to llvm.roundeven in default environment and both can be dropped. We'll end up with a funny situation, there are constrained intrinsics (experimental!) but not corresponding 'usual' intrinsics. This demonstrates that splitting an operation into constrained and non-constrained variants does not work in the case of `rint` and `nearbyint`.<br><div><div dir="ltr"><br></div><div dir="ltr"><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">As
for the target-specific intrinsics, you are correct that we need a plan for
that.</blockquote></div><div dir="ltr"><br></div><div dir="ltr">When making such plan we should keep in mind that some targets encode rounding mode in instructions, rather than in some hardware register. In this case "floating point environment" is an attribute of particular instruction. By the way, X86 target also has such property: EVEX prefix allows static rounding support or suppress-all-exceptions. Such properties are naturally modeled with metadata operands but splitting to constrained and non-constrained variants makes little sense.<br></div><div dir="ltr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">My suggestion would be that we should set the strictfp attribute on these intrinsics and provide the rounding mode and exception behavior arguments using an operand bundle.</blockquote><div dir="ltr"><br></div><div dir="ltr">This is an interesting variant. IIUC it means that FP environment is a property of a call rather that an instruction? That is some call may have rounding mode argument and another call of the same intrinsic may have not? It would the third way to express FP environment, together with the current per-intrinsic way and the rejected per-basic-block one. I wonder if we can model “inaccessibleMemOnly” or something like that using this way. The main justification of splitting an intrinsic to constrained and non-constrained variants is that one has side effect and the other does not. If we could deliberately assign this property to a particular call, we could eventually merge constrained and non-constrained intrinsics.<br></div><div dir="ltr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It’s probably best to say in the documentation that the llvm.nearbyint and llvm.rint functions “assume the default rounding mode, roundToNearest”. This will allow the optimizer to transform them as if they were rounding to nearest without requiring backends to use an encoding that enforces roundToNearest as the rounding mode for these operations.</blockquote><div dir="ltr"><br></div><div dir="ltr">Optimizer could make the same optimization with constrained nearbyint and rint, replacing them with llvm.roundeven, it is knows that the environment is default.<br></div><div dir="ltr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Also, we should take care to document the non-constrained forms of these intrinsics in a way that makes clear that we are “assuming” and not requiring that the operation has no side effects.</blockquote><div dir="ltr"><br></div><div dir="ltr">What non-constrained forms of rint/nearbyint can be used for? They are do the same job as llvm.roundeven does. They are useless. These intrinsics were introduced to represent C library functions rint/nearbyint, but the standard explicitly states that the result of either depends on current rounding mode. So these intrinsics should not be split into constrained and non-constrained forms, only the form that is ordered relative to other operations accessing FP environment may exist.<br></div><div dir="ltr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Here are some suggested wordings for the “Semantics” section of the langref for these functions:</blockquote><div dir="ltr"><br></div><div>Thank you!</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I’d like to also say that these intrinsics can be lowered to the corresponding libm functions, but I’m not sure all libm implementations meet the requirements above.</blockquote><div dir="ltr"><br></div><div dir="ltr">I think we should reference C standard rather than particular library. For example, semantics of roundeven:<br></div><div dir="ltr"><br></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>This function implements IEEE-754 operation ``roundToIntegralTiesToEven``. It</div></div><div><div>also behaves in the same way as C standard function ``roundeven``, except that</div></div><div><div>it does not raise floating point exceptions.</div></div></blockquote><div><div dir="ltr"><br></div><div dir="ltr">Thanks,<br>--Serge<br></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Mar 3, 2020 at 7:32 PM Hanna Kruppe <<a href="mailto:hanna.kruppe@gmail.com" target="_blank">hanna.kruppe@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi Andy,<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 2 Mar 2020 at 23:59, Kaylor, Andrew 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:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-US">
<div>
<p class="MsoNormal">Some clarification after getting feedback from Craig Topper….<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">It’s probably best to say in the documentation that the llvm.nearbyint and llvm.rint functions “assume the default rounding mode, roundToNearest”. This will allow the optimizer to transform them as if they were rounding to nearest without
requiring backends to use an encoding that enforces roundToNearest as the rounding mode for these operations. On modern x86 targets we can encode it either way, but it seems more consistent to continue using the current encoding which tells the processor to
use the current rounding mode. For other targets (including cases where x86 is forced to use x87 instructions), it may be much easier to leave this at the discretion of the backend.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Also, we should take care to document the non-constrained forms of these intrinsics in a way that makes clear that we are “assuming” and not requiring that the operation has no side effects.</p></div></div></blockquote><div> </div><div>Note that these aspects are shared by most other FP operations and already discussed in the LangRef section <<a href="https://llvm.org/docs/LangRef.html#floating-point-environment" target="_blank">https://llvm.org/docs/LangRef.html#floating-point-environment</a>> which currently reads:<br><br>> The default LLVM floating-point environment assumes that floating-point instructions do not have side effects. Results assume the round-to-nearest rounding mode. No floating-point exception state is maintained in this environment. Therefore, there is no attempt to create or preserve invalid operation (SNaN) or division-by-zero exceptions.<br>> <br>> The benefit of this exception-free assumption is that floating-point operations may be speculated freely without any other fast-math relaxations to the floating-point model.<br>> <br>> Code that requires different behavior than this should use the Constrained Floating-Point Intrinsics.<br><br>Your explanation of the implications for optimizers and backends seems like a useful addition to this section. As many intrinsics (not just nearbyint/rint) and instructions (fadd, fmul, etc.) behave this way, I think it would be more useful to consolidate all the information into this section and reference it from the relevant "Semantics" sections.<br><br>While we're on it, let me point out the consequences of breaking these assumptions are still fuzzy even with your clarifications. In general, when a compiler "assumes" something that is not actually true, it's useful to specify what exactly happens when the assumption is actually false, e.g. the result is an undefined value (undef/poison), or a non-deterministic choice is made (e.g. branching on poison, at the moment), or Undefined Behavior happens. In this sense, I wonder what should happen when the assumptions about rounding mode and FP exception state are broken? If it's going to take broader discussion to agree on an answer, that's probably out of scope for this thread, but perhaps there's a clear answer that just wasn't written down so far?<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div lang="EN-US"><div><p class="MsoNormal">For the constrained version of nearbyint, we
will require that the inexact exception is not raised (to be consistent with iEEE 754-2019’s roundToIntegral operations) and for the constrained version of rint we will require that the inexact exception is raised (to be consistent with iEEE 754-2019’s roundToIntegralExact
operation), but for the non-constrained forms it should be clear that the backend is free to implement this in the most efficient way possible, without regard to FP exception behavior.</p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Finally, I see now the problem with documenting these in terms of the IEEE operations, given that IEEE 754-2019 doesn’t describe an operation that uses the current rounding mode without knowing what that is. I see this as a problem of documentation
rather than one that presents any difficulty for the implementation. <u></u><u></u></p>
</div></div></blockquote><div><br></div><div>I'm not quite sure what you mean by "uses the current rounding without knowing what it is" --are you referring to the wobbly uncertainty caused by optimizations assuming one rounding mode but runtime code possibly using a different dynamic rounding mode? If so, explicitly defining what happens when dynamic and "assumed" rounding mode don't match (see above) also addresses this problem. Then the operations can be described like this:<br></div><div><br></div><div>> If a rounding mode is assumed [RNE for non-constrained intrinsic or roundingMode argument != fpround.dynamic] and the current dynamic rounding mode differs from the assumed rounding mode, [pick one: behavior is undefined / result is poison / ...]. Otherwise, X operation is performed with the current dynamic rounding mode [which equals the statically assumed rounding mode if this clause applies].</div><div><br></div><div>Best regards,<br>Hanna <br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div lang="EN-US"><div><p class="MsoNormal"></p>
<p class="MsoNormal">Here are some suggested wordings for the “Semantics” section of the langref for these functions:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">llvm.nearbyint::semantics<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">This function returns the same value as one of the IEEE 754-2019 roundToIntegral operations using the current rounding mode. The optimizer may assume that actual rounding mode is roundToNearest (IEEE 754: roundTiesToEven), but backends
may encode this operation either using that rounding mode explicitly or using the dynamic rounding mode from the floating point environment. The optimizer may assume that the operation has no side effects and raises no FP exceptions, but backends may encode
this operation using either instructions that raise exceptions or instructions that do not. The FP exceptions are assumed to be ignored.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">llvm.rint (delete, or identical semantics to llvm.nearbyint)<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">llvm.experimental.constrained.nearbyint::semantics<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">This function returns the same value as one of the IEEE 754-2019 roundToIntegral operations. If the roundingMode argument is fpround.dynamic, the behavior corresponds to whichever of the roundToIntegral operations matches the dynamic rounding
mode when the operation is executed. The optimizer may not assume any rounding mode in this case, and backends must encode the operation in a way that uses the dynamic rounding mode. Otherwise, the rounding mode may be assumed to be that described by the roundingMode
argument and backends may either use instructions that encode that rounding mode explicitly or use the current rounding mode from the FP environment.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The optimizer may assume that this operation does not raise the inexact exception when the return value differs from the input value, and if the exceptionBehavior argument is not fpexcept.ignore, the backend must encode this operation using
instructions that guarantee that the inexact exception is not raised. If the exceptionBehavior argument is fpexcept.ignore, backends may encode this operation using either instructions that raise exceptions or instructions that do not.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">llvm.experimental.constrained.rint::semantics<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">This function returns the same value as the IEEE 754-2019 roundToIntegralExact operation. If the roundingMode argument is fpround.dynamic, the behavior uses to the dynamic rounding mode when the operation is executed. The optimizer may
not assume any rounding mode in this case, and backends must encode the operation in a way that uses the dynamic rounding mode. Otherwise, the rounding mode may be assumed to be that described by the roundingMode argument and backends may either use instructions
that encode that rounding mode explicitly or use the current rounding mode from the FP environment.<u></u><u></u></p>
<p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal">If the exceptionBehavior argument is not fpexcept.ignore, the optimizer must assume that this operation will raise the inexact exception when the return value differs from the input value and the backend must encode this operation using
instructions that guarantee that the inexact exception is raised in that case. If the exceptionBehavior argument is fpexcept.ignore, backends may encode this operation using either instructions that raise exceptions or instructions that do not.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I’d like to also say that these intrinsics can be lowered to the corresponding libm functions, but I’m not sure all libm implementations meet the requirements above.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">-Andy<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div style="border-color:rgb(225,225,225) currentcolor currentcolor;border-style:solid none none;border-width:1pt medium medium;padding:3pt 0in 0in">
<p class="MsoNormal"><b>From:</b> llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>> <b>On Behalf Of
</b>Kaylor, Andrew via llvm-dev<br>
<b>Sent:</b> Monday, March 02, 2020 9:56 AM<br>
<b>To:</b> Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>>; Ulrich Weigand <<a href="mailto:Ulrich.Weigand@de.ibm.com" target="_blank">Ulrich.Weigand@de.ibm.com</a>><br>
<b>Cc:</b> LLVM Developers <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] Should rint and nearbyint be always constrained?<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I agree with Ulrich. The default behavior of LLVM IR is to assume that the roundToNearest is the current rounding mode everywhere. This corresponds to the C standard, which says that the user may only modify the floating point environment
if fenv access is enabled. In the latest version of the C standard, pragmas are added which can change the rounding mode for a region, and if these are implemented in clang the constrained versions of all FP operations should be used. However, outside of regions
where fenv access is enabled either by pragma or command line option, we are free to assume that the current rounding mode is the default rounding mode.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">So, llvm.rint and llvm.nearbyint (the non-constrained versions) can be specifically documented as performing their operation according to roundToNearest and clang can use them in the default case for the corresponding libm functions, and
llvm.experimental.constrained.rint and llvm.experimental.constrained.nearbyint can be documented as using the current rounding mode.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The only issue I see is that since we also assume FP operations have no side effects by default there is no difference between llvm.rint and llvm.nearbyint. I wouldn’t have a problem with dropping llvm.rint completely.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">As for the target-specific intrinsics, you are correct that we need a plan for that. I have given it some thought, but nothing is currently implemented. My suggestion would be that we should set the strictfp attribute on these intrinsics
and provide the rounding mode and exception behavior arguments using an operand bundle. We do still need some way to handle the side effects. My suggestion here is to add some new attribute that means “no side effects” in the absence of the strictfp attribute
and something similar to “inaccessibleMemOnly” in the presence of strictfp.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">We could make the new attribute less restrictive than inaccessibleMemOnly in that it only really needs to act as a barrier relative to other things that are accessing the fp environment. I believe Ulrich suggested this to me at the last
LLVM Developer Meeting.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">-Andy<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><b>From:</b> Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>>
<br>
<b>Sent:</b> Monday, March 02, 2020 8:10 AM<br>
<b>To:</b> Ulrich Weigand <<a href="mailto:Ulrich.Weigand@de.ibm.com" target="_blank">Ulrich.Weigand@de.ibm.com</a>><br>
<b>Cc:</b> Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>>; Cameron McInally <<a href="mailto:cameron.mcinally@nyu.edu" target="_blank">cameron.mcinally@nyu.edu</a>>; Kevin Neal <<a href="mailto:kevin.neal@sas.com" target="_blank">kevin.neal@sas.com</a>>;
LLVM Developers <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: Should rint and nearbyint be always constrained?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<blockquote style="border-color:currentcolor currentcolor currentcolor rgb(204,204,204);border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt">
<p class="MsoNormal">I'm not sure why this is an issue. Yes, these two intrinsics depend<br>
on the current rounding mode according to the C standard, and yes,<br>
LLVM in default mode assumes that the current rounding mode is the<br>
default rounding mode. But the same holds true for many other<br>
intrinsics and even the arithmetic IR operations like add.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal">Any other intrinsic, like `floor`, `round` etc has meaning at default rounding mode. But use of `rint` or `nearbyint` in default FP environment is strange, `roundeven` can be used instead. We could use more general intrinsics in all cases,
as the special case of default environment is not of practical interest.<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">There is another reason for special handling. Set of intrinsics includes things like `x86_sse_cvtss2si`. It is unlikely that all of them eventually get constrained counterpart. It looks more natural that such intrinsics are defined as accessing
FP environment and can be optimized if the latter is default. These two intrinsics could be a good model for such cases. IIUC, splitting entities into constrained or non-constrained is a temporary solution, ideally they will merge into one entity. We could
do it for some intrinsics now.<u></u><u></u></p>
<div>
<p class="MsoNormal"> <br clear="all">
<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">Thanks,<br>
--Serge<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Mar 2, 2020 at 8:58 PM Ulrich Weigand <<a href="mailto:Ulrich.Weigand@de.ibm.com" target="_blank">Ulrich.Weigand@de.ibm.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-color:currentcolor currentcolor currentcolor rgb(204,204,204);border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt">
<div>
<p style="margin-bottom:12pt"><tt><span style="font-size:10pt">Serge Pavlov <<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>> wrote on 02.03.2020 14:38:48:</span></tt><span style="font-size:10pt;font-family:"Courier New""><br>
<br>
<tt>> This approach has issues when applied to the intrinsics `rint` and </tt><br>
<tt>> `nearbyint`. Value returned by either of these intrinsics depends on</tt><br>
<tt>> current rounding mode. If they are considered as operation in </tt><br>
<tt>> default environment, they would round only to nearest. It is by far </tt><br>
<tt>> not the meaning of the standard C functions that these intrinsics represent.</tt><br>
</span><br>
<tt><span style="font-size:10pt">I'm not sure why this is an issue. Yes, these two intrinsics depend</span></tt><br>
<tt><span style="font-size:10pt">on the current rounding mode according to the C standard, and yes,</span></tt><br>
<tt><span style="font-size:10pt">LLVM in default mode assumes that the current rounding mode is the</span></tt><br>
<tt><span style="font-size:10pt">default rounding mode. But the same holds true for many other</span></tt><br>
<tt><span style="font-size:10pt">intrinsics and even the arithmetic IR operations like add.</span></tt><br>
<br>
<tt><span style="font-size:10pt">If you want to stop clang from making the default rounding mode</span></tt><br>
<tt><span style="font-size:10pt">assumption, you need to use the -frounding-math option (or one</span></tt><br>
<tt><span style="font-size:10pt">of its equivalents), which will cause clang to emit the corresponding</span></tt><br>
<tt><span style="font-size:10pt">constrained intrinsics instead, for those two as well all other</span></tt><br>
<tt><span style="font-size:10pt">affected intrinsics.</span></tt><br>
<br>
<tt><span style="font-size:10pt">I don't see why it would make sense to add another special case</span></tt><br>
<tt><span style="font-size:10pt">just for those two intrinsics ...</span></tt><br>
<br>
<br>
<tt><span style="font-size:10pt">Bye,</span></tt><br>
<tt><span style="font-size:10pt">Ulrich</span></tt><u></u><u></u></p>
</div>
</blockquote>
</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://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div>
</blockquote></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://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div>
</blockquote></div>
</blockquote></div>