Bug 7438 - add.ovf codegen incorrectly on amd64
Summary: add.ovf codegen incorrectly on amd64
Alias: None
Product: Runtime
Classification: Mono
Component: JIT ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2012-09-25 04:57 UTC by Rob Franken
Modified: 2012-09-28 20:22 UTC (History)
7 users (show)

Is this bug a regression?: ---
Last known good build:

Minimal code example (228 bytes, text/x-csharp)
2012-09-25 04:57 UTC, Rob Franken

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Rob Franken 2012-09-25 04:57:01 UTC
Created attachment 2612 [details]
Minimal code example

Compiling and running attached code gives an IndexOutOfRangeException. when compiling with the -checked+ flag this doesn't happen. This is the expected result.

Also moving the addition out of the square brackets to a seperate statement (using 2 extra variables) or adding a try catch statement around the assignment will make sure all addressing to the array succeed.
Comment 1 Rob Franken 2012-09-25 05:03:26 UTC
Sorry, Forgot to mention compiler version. Tested it both with as packaged in Debian Sid and with a fresh build from the 2.11.4 tgz from the download page.
Comment 2 Rob Franken 2012-09-25 08:56:35 UTC
Just tested, and the generated CIL binary does run on windows, so more likely to be a problem in the virtual machine.
Comment 3 Marek Safar 2012-09-25 13:39:48 UTC
I cannot reproduce the issue on x86 running mono master. What architecture are you running this on.
Comment 4 Rob Franken 2012-09-25 16:27:11 UTC
running on amd64 (x86_64)
Comment 5 Chris Howie 2012-09-25 18:56:28 UTC
Confirmed present on amd64 using Mono  The only difference between the CIL images is that "add.ovf" is used in place of "add" in the checked version, which hints at a JIT-compiler bug regarding the "add" opcode.
Comment 6 Csaba Halász 2012-09-25 20:15:57 UTC
The code blows during the second iteration.
Studying the AOT compiled code, it looks like the compiler decided to use 64 bit registers r13 and r14 for the loop variables:

    103b:       49 be 9c ff ff ff ff    mov    $0xffffffffffffff9c,%r14
    1042:       ff ff ff
    1045:       e9 66 00 00 00          jmpq   10b0 <Bugged_Main_string__+0xa0>
    104a:       48 8d 64 24 00          lea    0x0(%rsp),%rsp
    104f:       90                      nop
    1050:       49 bd 9c ff ff ff ff    mov    $0xffffffffffffff9c,%r13
    1057:       ff ff ff
[... more code using 64 bit r13/r14 omitted here ...]

However in the loop increment and condition check, it's using 32 bit arithmetic:

    10a4:       41 ff c5                inc    %r13d
    10a7:       41 83 fd 64             cmp    $0x64,%r13d
    10ab:       7c b3                   jl     1060 <Bugged_Main_string__+0x50>
    10ad:       41 ff c6                inc    %r14d
    10b0:       41 83 fe 64             cmp    $0x64,%r14d
    10b4:       7c 9a                   jl     1050 <Bugged_Main_string__+0x40>

Due to the nature of x86-64 architecture, the 32 bit increment will clear the top 32 bits of the register, so on the second iteration r13 will contain 0x00000000ffffff9d. In 32 bit arithmetic that correctly evaluates as -99, so the loop condition (which is checked using 32 bit instruction) is true. However the loop body uses 64 bit arithmetic, where this value evaluates to 4294967197 and that generates the exception.

I hope this helps somebody.
Comment 7 Marek Safar 2012-09-26 03:08:20 UTC
Comment 8 Zoltan Varga 2012-09-28 20:22:52 UTC
Fixed in master/2.10 branch.