<div>Hi Michael,</div><div><br></div><div>My main concern is performance in default mode, so I see the FENV fix as the side effect. :)</div><div><br></div><div>I looked at this very briefly before leaving my dev machine for the day. I think we're going to need a cmov conversion pass that happens very late (maybe this already exists but just isn't firing for the cases I looked at). Trying to convert these any sooner will likely be too harmful to the DAG. PowerPC has this functionality, so we should already have a model to share or steal from.</div><div><br><div class="gmail_quote"><div>On Thu, May 11, 2017 at 7:30 PM Michael Clark <<a href="mailto:michaeljclark@mac.com">michaeljclark@mac.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Hi Sanjay,</div><div><br></div><div>I can’t comment on the bug as I don’t have an LLVM bugzilla account. I’ve emailed bugs-admin to gain access to bugzilla so I can comment on the bug.</div><div><br></div><div>I note that on your bug that you have stated that the branch is faster than the conditional move. Faster code is a side effect of the fix in this particular case. The real issue is as Andrew mentioned, it that the predicate logic; the ISD:FSUB in particular is causing FE_INEXACT accrued exception state for exact conversions. </div><div><br></div><div>Here is some code that shows the error and has a workaround by forcing the compiler to create a branch by using inline asm for the conversion.</div><div><br></div><div><span class="m_-7068334004289141815Apple-tab-span" style="white-space:pre-wrap"> </span><a href="https://godbolt.org/g/huIgK1" target="_blank">https://godbolt.org/g/huIgK1</a></div><div><br></div><div>The bug affects both float to u64 and double to u64 conversions.</div><div><br></div><div>Expected output:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">$ clang <a href="http://fcvt-bug.cc" target="_blank">fcvt-bug.cc</a> <br>$ ./a.out <br>1 exact<br>1 inexact<br>1 exact<br>1 inexact<br>1 exact<br>1 inexact<br>1 exact<br>1 inexact</blockquote><div><br></div><div>Erroneous output:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>$ clang -DDISABLE_WORKAROUND <a href="http://fcvt-bug.cc" target="_blank">fcvt-bug.cc</a> </div><div>$ ./a.out </div><div>1 exact</div><div>1 inexact</div><div>1 inexact</div><div>1 inexact</div><div>1 exact</div><div>1 inexact</div><div>1 inexact</div><div>1 inexact</div></blockquote><div><br></div><div>Michael.</div></div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On 12 May 2017, at 11:36 AM, Sanjay Patel <<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>> wrote:</div><br class="m_-7068334004289141815Apple-interchange-newline"><div><div><div><div>Thanks, Andy. I'm not sure how to solve that or my case given the DAG's basic-block limit. Probably CodeGenPrepare or SelectionDAGBuilder...or we wait until after isel and try to split it up in a machine instruction pass.<br><br></div>I filed my example here:<br><a href="https://bugs.llvm.org/show_bug.cgi?id=33013" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=33013</a><br><br></div>Feel free to comment there and/or open a new bug for the <span style="font-size:9.5pt;font-family:consolas">FP_TO_UINT case.<br></span></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 11, 2017 at 4:20 PM, Kaylor, Andrew <span><<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div link="blue" vlink="purple" lang="EN-US">
<div class="m_-7068334004289141815m_-530121093589002012WordSection1"><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">Hi Sanjay,<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">The issue that Michael is talking about is that in SelectionDAGLegalize::ExpandNode() we’re doing this:<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas">
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue">case</span><span style="font-size:9.5pt;font-family:Consolas"> ISD::FP_TO_UINT: {<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> SDValue True, False;<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> EVT VT = Node->getOperand(0).getValueType();<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> EVT NVT = Node->getValueType(0);<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> APFloat apf(DAG.EVTToAPFloatSemantics(VT),<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> APInt::getNullValue(VT.getSizeInBits()));<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> APInt x = APInt::getSignMask(NVT.getSizeInBits());<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> (</span><span style="font-size:9.5pt;font-family:Consolas;color:blue">void</span><span style="font-size:9.5pt;font-family:Consolas">)apf.convertFromAPInt(x,
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue">false</span><span style="font-size:9.5pt;font-family:Consolas">, APFloat::rmNearestTiesToEven);<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> Tmp1 = DAG.getConstantFP(apf, dl, VT);<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> Tmp2 = DAG.getSetCC(dl, getSetCCResultType(VT),<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> Node->getOperand(0),<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> Tmp1, ISD::SETLT);<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0));<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas">
</span><span style="font-size:9.5pt;font-family:Consolas;color:green">// TODO: Should any fast-math-flags be set for the FSUB?</span><span style="font-size:9.5pt;font-family:Consolas"><u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT,<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> DAG.getNode(ISD::FSUB, dl, VT,<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> Node->getOperand(0), Tmp1));<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> False = DAG.getNode(ISD::XOR, dl, NVT, False,<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> DAG.getConstant(x, dl, NVT));<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> Tmp1 = DAG.getSelect(dl, NVT, Tmp2, True, False);<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas"> Results.push_back(Tmp1);<u></u><u></u></span></p><p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.5pt;font-family:Consolas">
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue">break</span><span style="font-size:9.5pt;font-family:Consolas">;<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:9.5pt;font-family:Consolas"> }</span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><a name="m_-7068334004289141815_m_-530121093589002012__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">This results in code that speculatively executes the FSUB and then uses a cmov instruction (based on whether or not the original value
was less than LLONG_MAX) to select between the direct FP_TO_SINT result and the result of the FSUB. If we assume that for most data sets a significant majority of values being converted this way will be less than LLONG_MAX then the processor should be able
to predict a branch here pretty reliably and so branching code would be faster than code that does a speculative FSUB followed by a cmov.<u></u><u></u></span></a></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">The question is, how do we need to change this to get the back end to generate a branch instead of a cmov. I’m guessing that there are circumstances in which
the target-specific backend would make that decision on its own and sink the FSUB, but for the X86 backend that doesn’t seem to be happening in this case. My inclination was to just rewrite the ExpandNode() code above to explicitly create a branch, but I
haven’t tried it yet.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">As a side effect, which is what originally drew Michael’s attention to this conversion, the INEXACT floating point flag is set even for exact conversions as a
result of the speculative FSUB. That’s how this got related to FENV_ACCESS support.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">I don’t know if there has been a bug opened for this issue. There was an earlier discussion here: <a href="https://groups.google.com/forum/#!topic/llvm-dev/Tl9SD-edUJI" target="_blank">https://groups.google.com/forum/#!topic/llvm-dev/Tl9SD-edUJI</a><u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">-Andy<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><a name="m_-7068334004289141815_m_-530121093589002012______replyseparator"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Sanjay Patel [mailto:<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>]
<br>
<b>Sent:</b> Thursday, May 11, 2017 2:06 PM<br>
<b>To:</b> Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>><br>
<b>Cc:</b> Michael Clark <<a href="mailto:michaeljclark@mac.com" target="_blank">michaeljclark@mac.com</a>>; llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] FENV_ACCESS and floating point LibFunc calls<u></u><u></u></span></p><div><div class="m_-7068334004289141815h5"><p class="MsoNormal"><u></u> <u></u></p>
<div>
<div><p class="MsoNormal">Sounds like the select lowering issue is definitely separate from the FENV work.<br>
<br>
Is there a bug report with a C or IR example? You want to generate compare and branch instead of a cmov for something like this?<u></u><u></u></p>
</div><p class="MsoNormal" style="margin-bottom:12.0pt"><br>
int foo(float x) {<br>
if (x < 42.0f)<br>
return x;<br>
return 12;<br>
}<br>
<br>
define i32 @foo(float %x) {<br>
%cmp = fcmp olt float %x, 4.200000e+01<br>
%conv = fptosi float %x to i32<br>
%ret = select i1 %cmp, i32 %conv, i32 12<br>
ret i32 %ret<br>
}<br>
<br>
$ clang -O2 cmovfp.c -S -o -<br>
movss LCPI0_0(%rip), %xmm1 ## xmm1 = mem[0],zero,zero,zero<br>
ucomiss %xmm0, %xmm1<br>
cvttss2si %xmm0, %ecx<br>
movl $12, %eax<br>
cmoval %ecx, %eax<br>
retq<br>
<br>
<u></u><u></u></p>
</div>
<div><p class="MsoNormal"><u></u> <u></u></p>
<div><p class="MsoNormal">On Thu, May 11, 2017 at 1:28 PM, Kaylor, Andrew via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<u></u><u></u></p>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">Hi Michael,</span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"> </span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">To be honest I haven’t started working on FP to integer conversions for FENV_ACCESS yet.</span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"> </span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">To some extent I would consider the issue that you found independent of what I’m doing to constrain
FP behavior. That is, I think we ought to make the change you’re asking for even apart from the FENV_ACCESS work. When I get to the conversions for FENV_ACCESS support it may require some additional constraints, but I think if the branching conversion is
usually faster (and it looks like it will be) then that should be the default behavior.</span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"> </span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">I’ll try to look into that. I’d offer to give you advice on putting together a patch, but I’m still
learning my way around the ISel code myself. I think I know enough to figure out what to do but not enough to tell someone else how to do it without a bunch of wrong turns.</span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"> </span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">-Andy</span><u></u><u></u></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"> </span><u></u><u></u></p><p class="MsoNormal"><a name="m_-7068334004289141815_m_-530121093589002012_m_5149843639143109846__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"> </span></a><u></u><u></u></p>
<div>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0in 0in 0in"><p class="MsoNormal"><a name="m_-7068334004289141815_m_-530121093589002012_m_5149843639143109846______replyseparato"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">
Michael Clark [mailto:<a href="mailto:michaeljclark@mac.com" target="_blank">michaeljclark@mac.com</a>]
<br>
<b>Sent:</b> Wednesday, May 10, 2017 7:59 PM<br>
<b>To:</b> Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>><br>
<b>Cc:</b> llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> FENV_ACCESS and floating point LibFunc calls</span><u></u><u></u></p>
</div>
</div>
<div>
<div><p class="MsoNormal"> <u></u><u></u></p><p class="MsoNormal">Hi Andy,<u></u><u></u></p>
<div><p class="MsoNormal"> <u></u><u></u></p>
</div>
<div><p class="MsoNormal">I’m interested to try out your patches…<u></u><u></u></p>
</div>
<div><p class="MsoNormal"> <u></u><u></u></p>
</div>
<div><p class="MsoNormal">I understand the scope of FENV_ACCESS is relatively wide, however I’m still curious if you managed to figure out how to prevent the SelectionDAGLegalize::ExpandNode() FP_TO_UINT
lowering of the FPToUI intrinsic from producing the predicate logic that incorrectly sets the floating point accrued exceptions due to unconditional execution of the ISD::FSUB node attached to the SELECT node. It’s a little above my head to try to solve this
issue with my current understanding of LLVM but I could give it a try. I’d need some guidance as to how the lowering of SELECT can be controlled. i.e. where LLVM decides whether and how to lower a select node as a branch vs predicate logic.<u></u><u></u></p>
</div>
<div><p class="MsoNormal"> <u></u><u></u></p>
</div>
<div><p class="MsoNormal">I’d almost forgotten that we microbenchmarked this and found the branching version is faster with regular input (< LLONG_MAX).<u></u><u></u></p>
</div>
<div><p class="MsoNormal"> <u></u><u></u></p>
</div>
<div><p class="MsoNormal" style="margin-bottom:12.0pt">- <a href="https://godbolt.org/g/ytgk7l" target="_blank">https://godbolt.org/g/ytgk7l</a><u></u><u></u></p>
</div>
<div><p class="MsoNormal">All, Where does LLVM decide to lower select as predicate logic vs branches and how does the cost model work? I’m curious about a tuning flag to generate branches instead of computing
both values and using conditional moves…<u></u><u></u></p>
</div>
<div><p class="MsoNormal"> <u></u><u></u></p>
</div>
<div><p class="MsoNormal">Best,<u></u><u></u></p>
</div>
<div><p class="MsoNormal">Michael.<u></u><u></u></p>
</div>
<div><p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div><p class="MsoNormal">On 11 May 2017, at 11:41 AM, via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<u></u><u></u></p>
</div><p class="MsoNormal"> <u></u><u></u></p>
<div><p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Helvetica",sans-serif">Hi all,<br>
<br>
Background<br>
I've been working on adding the necessary support to LLVM for clang to be able to support the STDC FENV_ACCESS pragma, which basically allows users to modify rounding mode at runtime and depend on the value of floating-point status flags or to unmask floating
point exceptions without unexpected side effects. I've committed an initial patch (r293226) that adds constrained intrinsics for the basic FP operations, and I have a patch up for review now (</span><a href="https://reviews.llvm.org/D32319" target="_blank"><span style="font-size:9.0pt;font-family:"Helvetica",sans-serif">https://reviews.llvm.org/D32319</span></a><span style="font-size:9.0pt;font-family:"Helvetica",sans-serif">)
that adds constrained versions of a number of libm-like FP intrinsics.<br>
<br>
Current problem<br>
Now I'm trying to make sure I have a good solution for the way in which the optimizer handles recognized calls to libm functions (sqrt, pow, cos, sin, etc.). Basically, I need to prevent all passes from making any modifications to these calls that would make
assumptions about rounding mode or improperly affect the FP status flags (either suppressing flags that should be present or setting flags that should not be set). For instance, there are circumstances in which the optimizer will constant fold a call to one
of these functions if the value of the arguments are known at compile time, but this constant folding generally assumes the default rounding mode and if the library call would have set a status flag, I need the flag to be set.<br>
<br>
Question<br>
My question is, can/should I just rely on the front end setting the "nobuiltin" attribute for the call site in any location where the FP behavior needs to be restricted?<br>
<br>
Ideally, I would like to be able to conditionally enable optimizations like constant folding if I am able to prove that the rounding mode, though dynamic, is known for the callsite at compile time (the constrained intrinsics have a mechanism to enable this),
but at the moment I am more concerned about correctness and would be willing to sacrifice optimizations to get correct behavior. Long term, I was thinking that maybe I could do something like attach metadata to indicate rounding mode and exception behavior
when they were known.<br>
<br>
Is there a better way to do this?<br>
<br>
Thanks,<br>
Andy</span><u></u><u></u></p>
</div>
</blockquote>
</div><p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
</div>
</div>
</div><p class="MsoNormal" style="margin-bottom:12.0pt"><br>
_______________________________________________<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="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><u></u><u></u></p>
</blockquote>
</div><p class="MsoNormal"><u></u> <u></u></p>
</div>
</div></div></div>
</div>
</blockquote></div><br></div>
</div></blockquote></div><br></div></blockquote></div></div>