<div dir="ltr"><div class="gmail_extra" style>I think this entire conversation is going a bit off the rails. Let's try to stay focused on the specific request, and why there (may) be problems with it.</div><div class="gmail_extra">
<br><div class="gmail_quote">On Sun, Apr 7, 2013 at 11:50 AM, Cameron McInally <span dir="ltr"><<a href="mailto:cameron.mcinally@nyu.edu" target="_blank" class="cremed">cameron.mcinally@nyu.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
To be clear, you're asking to turn off a set of optimizations. That<br>
is, you're asking to make code in general run slower, so that you can<br>
get a particular behavior on some CPUs in unusual cases.<br></blockquote><div><br></div></div><div>I respectfully disagree. I am asking for an *option* to turn off a set of optimizations; not turn off optimizations in general. I would like to make it easy for a compiler implementor to choose the desired behaviour. I whole-heartedly believe that both behaviours (undefined and trap) have merit.</div>
</blockquote></div><br>I think you're both misconstruing what this would involve.</div><div class="gmail_extra"><br></div><div class="gmail_extra" style>You're actually asking for the formal model of the LLVM IR to be *parameterized*. In one mode, an instruction would produce undefined behavior on division, and in another mode it would produce a trap. Then you are asking for the optimizer stack to support either semantic model, and produce efficient code regardless.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>This is completely intractable for LLVM to support. It would make both the optimizers and the developers of LLVM crazy to have deep parameterization of the fundamental semantic model for integer division.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>The correct way to support *exactly* reproducing the architectural peculiarities of the x86-64 integer divide instruction is to add a target-specific intrinsic which does this. It will have defined behavior (of trapping in some cases) as you want, and you can emit this in your FE easily. However, even this has the risk of incurring a high maintenance burden. If you want much in the way of optimizations of this intrinsic, you'll have to go through the optimizer and teach each pass about your intrinsic. Some of these will be easy, but some will be hard and there will be a *lot* of them. =/</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>Cameron, you (and others interested) will certainly need to provide all of the patches and work to support this if you think this is an important use case, as the existing developers have found other trade-offs and solutions. And even then, if it requires really substantial changes to the optimizer, I'm not sure it's worth pursuing this in LLVM. My primary concerns are two-fold. First, I think that the amount of work required to recover the optimizations which could theoretically apply to both of these operations will be massive. Second, I fear that after having done this work, you will immediately find the need to remove some other undefined behavior from the IR which happens to have defined behavior on x86-64.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>Fundamentally, the idea of undefined behavior is at the core of the design of LLVM's optimizers. It is leveraged everywhere, and without it many algorithms that are fast would become slow, transformations that are cheap would become expensive, passes that operate locally would be forced to operate across ever growing scopes in order to be certain the optimizations applied in this specific case. Trying to remove undefined behavior from LLVM seems unlikely to be a productive pursuit.</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>More productive (IMO) is to emit explicit guards against the undefined behavior in your language, much as -fsanitize does for undefined behavior in C++. Then work to build a mode where a specific target can take advantage of target specific trapping behaviors to emit these guards more efficiently. This will allow LLVM's optimizers to continue to function in the world they were designed for, and with a set of rules that we know how to build efficient optimizers around, and your source programs can operate in a world with checked behavior rather than undefined behavior. As a useful side-effect, you can defer the target-specific optimizations until you have benchmarks (internally is fine!) and can demonstrate the performance problems (if any).</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>Cameron, you may disagree, but honestly if you were to convince folks here I think it would have happened already. I'm not likely to continue the theoretical debate about whether LLVM's stance on UB (as I've described above) is a "good" or "bad" stance. Not that I wouldn't enjoy the debate (especially at a bar some time), but because I fear it isn't a productive way to spend the time of folks on this list. So let's try to stick to the technical discussion of strategies, costs, and tradeoffs.</div>
</div>