<div class="gmail_quote">On 8 February 2012 15:54, David A. Greene <span dir="ltr"><<a href="mailto:dag@cray.com" target="_blank">dag@cray.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div>Nick Lewycky <<a href="mailto:nlewycky@google.com" target="_blank">nlewycky@google.com</a>> writes:<br>
<br>
>     Whether generic IR is a "win" isn't the primary issue here.  The issue<br>
>     is that the user wrote code using intrinsics and expects that exact code<br>
>     to be in the asm.  Whether or not that is the best performing code<br>
>     possible doesn't matter.  It's what they want and we have to respect it.<br>
>     Our customers demand it.<br>
><br>
> Okay. This is a different issue then, and isn't even solved by using<br>
> intrinsics; the optimization passes are absolutely allowed to modify<br>
> uses of intrinsics. We do this in obvious cases for things like memset<br>
> or ctz, but there is no reason the optimization passes won't optimize<br>
> the llvm.x86 intrinsics too. It's rare, but you can see code in<br>
> ValueTracking.cpp that will analyze Intrinsic::x86_sse42_crc32_64_8<br>
> for one example, ConstantFolding.cpp will fold<br>
> through x86_sse_cvtss2si for another.<br>
<br>
</div>That seems like a mistake and is not what I would expect to happen with<br>
intrinsics.  I can understand why compiler developers might want to do<br>
that but some users will be surprised.<br></blockquote><div><br></div><div>No, it's not the compiler developers. Our programmers expect the compiler to be capable of comprehending what the builtins mean and perform constant folding, licm, etc., and will file bugs when we don't emit optimal code.</div>


<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We need some way to provide the kind of guarantee I'm talking about.<br></blockquote><div><br></div>


<div>Yep.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>> Suppose you emit code like this: create your own functions with<br>
> definitions that use the IR implementations, and mark them<br>
> noinline. At the very end, you inline them with a pass that calls<br>
> InlineFunction() directly. Does this preserve the order, or do you<br>
> still have trouble with the backend doing too much reordering?<br>
<br>
</div>It's not just reordering.  Instcombine, dagcombine, etc. do a lot of<br>
massaging.<br></blockquote><div><br></div><div>Sure, but with what I proposed instcombine can't touch them (technically it *can*, but it won't do anything since each little intrinsic definition is already locally optimal). If you really have problems with the IR-level optimizers messing with them, you can make the functions declarations until you reach your IR-level pass, filling in their function bodies just before you run InlineFunction.</div>


<div><br></div><div>However, DAGCombine might fold them. If this is a problem in practice, my next idea is to wrap the functions in compiler barriers. Would that sufficient to prevent the problems you'd have?</div><div>

<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Again, what is the trouble with keeping intrinsics?  Why rip them out if<br>
people find them useful and necessary?  If the behavior of the optimizer<br>
changes wrt the intrinsics, we can deal with that when it happens.<br></blockquote><div><br></div><div>Your argument that the intrinsics are useful is falling flat because the use-case you've given is not one that would be solved by the presence of intrinsics. Just having intrinsics doesn't guarantee that they won't be "massaged" by the compiler. Also, waiting until you encounter a problem with the optimizer is only deferring the problem; when you bring up that issue the response will be "working as intended" and we'll be right back here.</div>


<div><br></div><div>It's entirely possible that the solution to your problem will involve intrinsics, but we have to work out exactly what. We could try adding an i1 flag to the intrinsics that indicate whether it should be treated as volatile. We could add a volatile bit to the IntrinsicInst/CallInst, maybe. We could add a new bit to some immutable spot (similar to TargetLibraryInfo) to indicate whether intrinsics are sacred or not. We could turn it around and say that the compiler may not optimize intrinsics except in a single pass, much like how only SimplifyLibCalls was only place allowed to assume that C functions had the behaviour their names implied (before we had TargetLibraryInfo).</div>

<div><br></div><div>I'm trying to start with approaches that serve your use-case with the minimal change to LLVM first.</div><div><br></div><div>Nick</div><div><br></div>
</div>