Home Dashboard Directory Help
Search

JIT optimizer error when loop controlling variable approaches Int.MaxValue by Ben Voigt


Status: 

Closed
 as Fixed Help for as Fixed


1
0
Sign in
to vote
Type: Bug
ID: 674232
Opened: 6/5/2011 10:10:12 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
0
Workaround(s)
view
0
User(s) can reproduce this bug

Description

The optimizer causes the loop in the attached code to terminate early and give bogus results. No exception is reported. The repro case does not contain any unsafe code.

I believe the error is in the JIT optimizer, not the C# compiler, because hand inspection of the generated MSIL doesn't show anything obviously wrong, and the problem does not recur when the Visual Studio debugger is attached.
Details
Sign in to post a comment.
Posted by Ben Voigt on 6/13/2011 at 12:09 PM
Thanks very much Grant for looking into that MSIL. The behavior with .ovf and .un modifiers gets complicated quickly, your analysis was invaluable.

Since the C# spec allows adding a pointer and UInt32, conversion to Int32 should not occur. Therefore I've filed a separate bug against the C# compiler for that issue:
https://connect.microsoft.com/VisualStudio/feedback/details/675205/c-compiler-performs-sign-extension-during-unsigned-pointer-arithmetic
Posted by Microsoft on 6/13/2011 at 11:30 AM
Thank you for the link. I responed to that issue on stack overflow. It is a different issue (technically not a bug in anythign except the user's code).

Grant Richins
Senior Developer
CLR Codegen Team
Posted by Ben Voigt on 6/12/2011 at 12:46 PM
Grant, I don't need a workaround, since the code I used to reveal the problem was only a learning exercise.

However, another incident has been reported, which looks like it may be related to this problem (an unsigned constant outside the range of Int32 wrapping around and being treated as signed).

Please check whether this issue impacts http://stackoverflow.com/questions/6321650/64-bit-pointer-arithmetic-in-c-check-for-arithmetic-overflow-changes-behavior/6324164#6324164
Posted by Microsoft on 6/10/2011 at 4:37 PM
Thank you Ben for reporting this issue. Your analysis is correct. This is a bug in the x64 JIT. I am working on fxing this for a future release. Do you need help finding a workaround in your code?

Grant Richins
Senior Developer
CLR Codegen Team
Posted by MS-Moderator07 [Feedback Moderator] on 6/7/2011 at 1:29 AM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.


Posted by MS-Moderator01 on 6/5/2011 at 10:48 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Posted by Ben Voigt on 6/5/2011 at 10:32 PM
Ok, now I am sure.

The compiler has converted:

    if (i < 2000000000) loop

into

    if (i*2 < 4000000000) loop

because it already has i*2 in a register in order to use as the increment in the inner loop. This is generally a valid transformation, but scaling the constant overflowed the range of a 32-bit signed integer.
Posted by Ben Voigt on 6/5/2011 at 10:22 PM
Not 100% sure, but I think this instruction is the problem:

cmp         ebp,0EE6B2804h
Sign in to post a workaround.