[LLVMdev] Integer divide by zero

Chandler Carruth chandlerc at google.com
Sun Apr 7 15:23:04 PDT 2013


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.

On Sun, Apr 7, 2013 at 11:50 AM, Cameron McInally
<cameron.mcinally at nyu.edu>wrote:

> To be clear, you're asking to turn off a set of optimizations. That
>> is, you're asking to make code in general run slower, so that you can
>> get a particular behavior on some CPUs in unusual cases.
>>
>
> 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.
>

I think you're both misconstruing what this would involve.

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.

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.

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. =/


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.


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.

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).

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130407/da362a0a/attachment.html>


More information about the llvm-dev mailing list