[rust-dev] Integer overflow, round -2147483648

Daniel Micay danielmicay at gmail.com
Sun Jun 22 22:05:42 PDT 2014


On 23/06/14 12:46 AM, comex wrote:
> On Mon, Jun 23, 2014 at 12:35 AM, Daniel Micay <danielmicay at gmail.com> wrote:
>> An operation that can unwind isn't pure. It impedes code motion such as
>> hoisting operations out of a loop, which is very important for easing
>> the performance issues caused by indexing bounds checks. LLVM doesn't
>> model the `nounwind` effect on functions simply for fun.
> 
> No it doesn't!  Or maybe it does today, but an unwindable operation is
> guaranteed to be repeatable without consequence, which I'd like to
> think can account for most cases where operations are hoisted out of
> loops (again, could be wrong :), and not to modify any memory (unless
> it traps, but in Rust at that point you are guaranteed to be exiting
> the function immediately).

The call we make to perform unwinding isn't a pure function though, it's
aware of the context causing it to unwind. As long as we're supporting
stuff like backtraces outside of a debugger, that's going to be the case.

If it was pure beyond not being `nounwind` then LLVM would have more
freedom to move it around, but it would still cause more problems than
using `llvm.trap` (abort).

> In particular, the only reason I can see why an impure operation would
> require repeating a bounds check is if the compiler thinks it could
> modify the size of the array, or the index, or something else in
> memory.  But it cannot.
> 
> Yeah, yeah, Rust is designed for 2014 not 2024, and I admit "LLVM
> cannot do this right now" is a perfectly good reason in this context.
> But I want to differentiate the different arguments being made here.
>
>> Unwinding is a stateful effect, and any code that would be otherwise
>> pure is no longer pure if it has the potential to unwind. It's not
>> simply a matter of unwinding or not unwinding, the compiler needs to
>> ensure that the source of the unwinding is the same.
> 
> Only if it crosses initialization of objects with destructors.  It
> doesn't matter if the stack trace is off.
> 
>> I provided an example demonstrating the cost with `clang`.
> 
> First of all, that's including actual bounds checks as opposed to
> merely assuming impurity/unwinding, no?  Again, simply to
> differentiate the arguments...

It's just a measurement of the overflow checks on signed/unsigned
integers. It does introduce a form of impurity since it's aborting in
branches, but it's a simpler form of impurity than unwinding where the
code continues running based on the context where it was thrown.

> Second of all, it may be possible to do the checks more efficiently.
> I should look at clang's assembly output.

LLVM actually has intrinsics for checked arithmetic to avoid screwups in
code generation. I don't think it's going to get any better on x86 at a
code generation level.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140623/6be96045/attachment.sig>


More information about the Rust-dev mailing list