[LLVMdev] Integer divide by zero

Cameron McInally cameron.mcinally at nyu.edu
Mon Apr 8 08:45:16 PDT 2013


On Mon, Apr 8, 2013 at 1:34 AM, Chandler Carruth <chandlerc at google.com>wrote:

> On Sun, Apr 7, 2013 at 9:28 PM, Cameron McInally <cameron.mcinally at nyu.edu
> > wrote:
>
>> 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).
>>>
>>
>> Regrettably, this implementation does not suit my needs.
>>
>
> I'm curious why you think so... I think it would very closely match your
> needs:
>

It's my current understanding that the actual division would be constant
folded away and I would be left with only the guard. Later, the guard would
be proved always true. I could, of course, be mistaken.

I checked out Clang with -fsanitize=integer-divide-by-zero this weekend and
saw similar in the assembly. I also noticed that the division operands are
still around in the assembly. If it would be possible to recreate the div
instructions, I would be thrilled.



>
>
>> The constant folding would still occur
>>
>
> No? At least, I don't see why.
>
> I don't know what your frontend is doing (but my impression is that it is
> not Clang? If I'm wrong, let me know...)
>

It is not Clang. Our compiler has proprietary frontends, optimizer,
vectorizer, and more. You may have noticed that I don't often share LLVM IR
on the list. Our IR has tons of proprietary changes to it. But, I digress.



> but the common idiom is to emit nothing as a constant other than immediate
> values, and let LLVM's optimizers figure it out.
>

Our pre-LLVM optimizer may be a culprit here. With the original test case I
provided, our inliner will inline both foo(...) and bar(...). In main(), we
end up calling CreateSDiv in the IRBuilder with two constants, i.e. (6/0).

Would Clang snap these constants into temporaries? Or, does Clang maintain
the original source structure? Sorry for these simple questions, I have no
insight to Clang at all.



> A consequence of this pattern combined with inserting guards is that (at
> most) the optimizer will fold directly to the trap. You should be able to
> control the exact structure in the FE though.
>

> and I would like to produce the actual division, since the instruction is
>> non-maskable on x86.
>>
>
> Yes, and this is the point I was driving at with the comments about a
> target specific optimization. It is reasonable for the x86 backend to
> recognize the pattern of testing for a zero divisor and trapping if it
> occurs, and transform that into an unconditional divide relying on the
> hardware trap instead. I think it is not unreasonable to have this strategy
> result in one of two generated code patterns in the overwhelming majority
> of cases:
>

I'm going to be nitpicky over this. It's really not my intention to be
unreasonable. I hope you can understand.


> 1) An unconditional trap because the optimizer proved divide by zero
>

This isn't desirable for me. I am afraid an unconditional trap in the
assembly will just confuse a user. I suspect that a user will trigger this
code and immediately report a compiler bug that we've inserted a rogue
trap.



> 2) A direct divide instruction which relies on the x86 trapping behavior.
>

This would be great. Would I be able to accurately recreate the actual
constant divide that was folded away? Originally, I had suspected that the
operands would be long gone or at least intractable. Again, this may sound
unreasonable, but I would like to keep the division intact so that a user
can see where their code went wrong in the assembly. Sorry in advance if
I'm misunderstanding.

Thanks again, Chandler.

-Cameron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130408/5375d098/attachment.html>


More information about the llvm-dev mailing list