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

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 674232 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 6/5/2011 10:10:12 PM
Access Restriction Public


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


    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