<div dir="ltr">One of sane methods to tackle this problem of enabling without touching default optimizer behavior might be filtering out passes or sub-passes that may violate the needs of FENV_ACCESS. I don't know that pass or subpasses are modular enough to do this yet, but if we can come up with something like a table-driven approach to pick which set of passes to run, that would at least be a start. I'd imagine a lot of the passes initially won't even get to run (even the ones that are necessary to compilation).<div><br></div><div>-Kevin</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 20, 2017 at 1:50 PM, Kaylor, Andrew <span dir="ltr"><<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 lang="EN-US" link="blue" vlink="purple">
<div class="m_4771653393985072493WordSection1"><span class="">
<p class="MsoNormal"><span style="font-size:9.5pt">> This seems like it was done for perf reason (mispredict). Conditional-to-cmov transformation should keep<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:9.5pt">> from introducing additional observable side-effects, and it's clear that whatever did this did not account
<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:9.5pt">> for floating point exception.<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>
</span><p class="MsoNormal"><a name="m_4771653393985072493__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">That’s a very reasonable statement, but I’m not sure it corresponds to the way we have typically approached this sort of problem.<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">In particular, there has been a de facto standard practice (and it has even been openly stated and agreed upon once or twice) of assuming default rounding mode
 and ignoring FP exceptions in the default (and currently only) optimization path for FP-related instructions.  That is, clang/LLVM didn’t just not support FENV_ACCESS by indifference but rather we have made conscious decisions to allow transformations that
 violate the needs of FENV_ACCESS when doing so can improve the performance of generated code.  Basically, we more or less pretend that floating point status bits don’t exist (at least before you get to the target-specific backend).<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">You’ll find that the X86 backend doesn’t even model MXCSR at the moment.  I tried to add it recently and it kind of blew up before I had even modeled it for anything
 other than LDMXCSR and STMCXSR.  We may want to address that at some point, but right now it just isn’t there.<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">When we discussed how FENV_ACCESS support should be implemented, Chandler proposed that when restricted modes (whether FENV_ACCESS or any other front end-specific
 analogous behavior) were not being used the optimizer should be able to behave as described above and that nothing done to support restricted FP behavior should complicate or restrict the default optimizer behavior.  This was met with general agreement at
 the time.<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 mention all this as prologue to saying that while we should do something to get FPToUI lowered without incorrectly setting FP exception status bits, it isn’t
 necessarily what we want as the default behavior.<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 would also like to add that I personally am very pleased that you discovered this issue and have gotten as far as you have in the analysis of the problem. 
 I’m in the process of adding constrained versions of various FP intrinsics (I have a patch ready to be sent out today) and what I’ve done up to now has been to simply translate the constrained operations into their traditional representations somewhere in
 the ISel process.  I was aware that something would need to be done in the codegen space to continue protecting these operations, but I was kind of hoping that the actual instruction selection would be reasonably safe.  FWIW, FPToUI is not one of the parts
 my pending patch addresses.<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"><a name="m_4771653393985072493______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"> llvm-dev [mailto:<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@<wbr>lists.llvm.org</a>]
<b>On Behalf Of </b>Flamedoge via llvm-dev<br>
<b>Sent:</b> Wednesday, April 19, 2017 10:14 AM<br>
<b>To:</b> Michael Clark <<a href="mailto:michaeljclark@mac.com" target="_blank">michaeljclark@mac.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> Re: [llvm-dev] [cfe-dev] FE_INEXACT being set for an exact conversion from float to unsigned long long<u></u><u></u></span></p><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">> <span style="font-size:9.5pt">Are we better off using branches instead of cmove to implement FP to<br>
unsigned i64?</span><u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.5pt">This seems like it was done for perf reason (mispredict). Conditional-to-cmov transformation should keep from introducing additional observable side-effects, and it's clear that whatever did this did not account
 for floating point exception.</span><u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Wed, Apr 19, 2017 at 10:01 AM, Michael Clark 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">Changing the list from cfe-dev to llvm-dev<u></u><u></u></p>
</div>
<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">On 20 Apr 2017, at 4:52 AM, Michael Clark <<a href="mailto:michaeljclark@mac.com" target="_blank">michaeljclark@mac.com</a>> wrote:<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<div>
<p class="MsoNormal">I’m getting close. I think it may be an issue with an individual intrinsic. I’m looking for the X86 lowering of Instruction::FPToUI.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I found a comment around the rationale for using a conditional move versus a branch. I believe the predicate logic using a conditional move is causing INEXACT to be set from the other side of the predicate as the lowered x86_64 code executes
 both conversions whereas GCC uses a branch. That seems to be the difference.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I can’t find FPToUI in llvm/lib/Target/X86 so I’m trying to figure out what the cast gets renamed to in the target layer so I can find where the sequence is emitted.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">$ more llvm/lib/Target/X86//README-<wbr>X86-64.txt<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">Are we better off using branches instead of cmove to implement FP to<br>
unsigned i64?<br>
<br>
_conv:<br>
        ucomiss LC0(%rip), %xmm0<br>
        cvttss2siq      %xmm0, %rdx<br>
        jb      L3<br>
        subss   LC0(%rip), %xmm0<br>
        movabsq $-9223372036854775808, %rax<br>
        cvttss2siq      %xmm0, %rdx<br>
        xorq    %rax, %rdx<br>
L3:<br>
        movq    %rdx, %rax<br>
        ret<br>
<br>
instead of<br>
<br>
_conv:<br>
        movss LCPI1_0(%rip), %xmm1<br>
        cvttss2siq %xmm0, %rcx<br>
        movaps %xmm0, %xmm2<br>
        subss %xmm1, %xmm2<br>
        cvttss2siq %xmm2, %rax<br>
        movabsq $-9223372036854775808, %rdx<br>
        xorq %rdx, %rax<br>
        ucomiss %xmm1, %xmm0<br>
        cmovb %rcx, %rax<br>
        ret<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">On 19 Apr 2017, at 2:10 PM, Michael Clark <<a href="mailto:michaeljclark@mac.com" target="_blank">michaeljclark@mac.com</a>> wrote:<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">On 19 Apr 2017, at 1:14 PM, Tim Northover <<a href="mailto:t.p.northover@gmail.com" target="_blank">t.p.northover@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On 18 April 2017 at 15:54, Michael Clark via cfe-dev<br>
<<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
<br>
<u></u><u></u></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">The only way towards completing a milestone is via fixing a number of small issues along<br>
the way…<u></u><u></u></p>
</blockquote>
<p class="MsoNormal"><br>
I believe there's more to it than that. None of LLVM's optimizations<br>
are aware of this extra side-channel of information (with possible<br>
exceptions like avoiding speculating fdiv because of unavoidable<br>
exceptions).<br>
<br>
>From what I remember, the real proposal is to replace all<br>
floating-point IR with intrinsics when FENV_ACCESS is on, which the<br>
optimizers by default won't have a clue about and will treat<br>
conservatively (essentially like they're modifying external memory).<br>
<br>
So be careful with drawing conclusions from small snippets; you're<br>
probably not seeing the full range of LLVM's behaviour.<u></u><u></u></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">Yes. I’m sure.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">It reproduces with just the cast on its own: <a href="https://godbolt.org/g/myUoL2" target="_blank">https://godbolt.org/g/<wbr>myUoL2</a><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">It appears to be in the LLVM lowering of the fptoui intrinsic so it must MC layer optimisations.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="margin-left:30.0pt;margin-right:0in">
<div>
<p class="MsoNormal"><span style="font-family:Courier">; Function Attrs: noinline nounwind uwtable</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:Courier">define i64 @_Z7fcvt_luf(float %f) #0 {</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:Courier">  %1 = alloca float, align 4</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:Courier">  store float %f, float* %1, align 4</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:Courier">  %2 = load float, float* %1, align 4</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:Courier">  %3 = fptoui float %2 to i64</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:Courier">  ret i64 %3</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:Courier">}</span><u></u><u></u></p>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">GCC performs a comparison with ucomiss and branches whereas Clang computes both forms and predicates the result using a conditional move. One of the conversions obviously is setting the INEXACT MXCSR flag.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Clang lowering (inexact set when result is exact):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="margin-left:30.0pt;margin-right:0in">
<p class="MsoNormal"><span style="font-family:Courier">fcvt_lu(float):<br>
        movss   xmm1, dword ptr [rip + .LCPI1_0] # xmm1 = mem[0],zero,zero,zero<br>
        movaps  xmm2, xmm0<br>
        subss   xmm2, xmm1<br>
        cvttss2si       rax, xmm2<br>
        movabs  rcx, -9223372036854775808<br>
        xor     rcx, rax<br>
        cvttss2si       rax, xmm0<br>
        ucomiss xmm0, xmm1<br>
        cmovae  rax, rcx<br>
        ret</span><u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">GCC lowering (sets flags correctly):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="margin-left:30.0pt;margin-right:0in">
<p class="MsoNormal"><span style="font-family:Courier">fcvt_lu(float):<br>
        ucomiss xmm0, DWORD PTR .LC0[rip]<br>
        jnb     .L4<br>
        cvttss2si       rax, xmm0<br>
        ret<br>
.L4:<br>
        subss   xmm0, DWORD PTR .LC0[rip]<br>
        movabs  rdx, -9223372036854775808<br>
        cvttss2si       rax, xmm0<br>
        xor     rax, rdx<br>
        ret</span><u></u><u></u></p>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><br>
______________________________<wbr>_________________<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/<wbr>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>