Closed
Bug 700620
Opened 13 years ago
Closed 12 years ago
jit/interpreter disagree about pre-increment on :int at int.MAX_VALUE
Categories
(Tamarin Graveyard :: Baseline JIT (CodegenLIR), defect)
Tamarin Graveyard
Baseline JIT (CodegenLIR)
Tracking
(Not tracked)
RESOLVED
FIXED
People
(Reporter: pnkfelix, Assigned: wmaddox)
References
Details
Attachments
(5 files, 2 obsolete files)
9.13 KB,
patch
|
edwsmith
:
feedback+
|
Details | Diff | Splinter Review |
13.35 KB,
patch
|
edwsmith
:
review+
|
Details | Diff | Splinter Review |
10.49 KB,
text/plain
|
Details | |
4.22 KB,
patch
|
edwsmith
:
review+
|
Details | Diff | Splinter Review |
10.47 KB,
text/plain
|
Details |
(Uncovered while trying to isolate components of Bug 700613; but I actually think this is unrelated.) var u:uint; var i:int; u = uint.MAX_VALUE; i = int.MAX_VALUE; trace([++u, ++i]); Interpeter for both 32- and 64-bit DebugDebugger avmshell says: 4294967296,2147483648 JIT for both 32-bit and 64-bit DebugDebugger avmshell says: 4294967296,-2147483648
Reporter | ||
Updated•13 years ago
|
Blocks: interp_jit_semantics
Assignee | ||
Comment 1•12 years ago
|
||
The attached test case not only demonstrates the problem above, but illustrates another error that manifests in both the interpreter and the JIT: var u:uint; u = uint.MAX_VALUE; /* 4294967295 */ ++u == 4294967296 /* expected 0; FAIL */ u = uint.MIN_VALUE; /* 0 */ --u == -1 /* expected 4294967295; FAIL */ It appears that this is an ASC problem. The expression '++i', for an 'int' variable 'i' is compiled like this: 37 getlocal2 38 increment_i 39 dup 40 convert_i 41 setlocal2 /* incremented value on stack, but properly wrapped. convert_i is redundant. */ The increment_i opcode always returns an 'int' result, as if toInt32() had been called on a result computed as Number. In contrast, the expression 'u++' with a 'uint' variable 'u' is compiled like this: 143 getlocal1 144 increment 145 dup 146 convert_u 147 setlocal1 /* incremented value on the stack here */ Here, the incremented value is computed as a Number, but converted to 'uint' prior to assignment to 'u'. Unfortunately, the value of the expression is not converted. I believe that the 'int' case is correct, but an AS3 spec guru should confirm.
Assignee | ||
Updated•12 years ago
|
Attachment #597631 -
Attachment is patch: false
Assignee | ||
Comment 2•12 years ago
|
||
The cause of the original error is the use of the FAST_INC_MAYBE and FAST_DEC_MAYBE fastpaths for the increment_i and decrement_i opcodes as well as for the unspecialized increment and decrement opcodes. If the argument is a (boxed) double, the fastpath will perform the increment/decrement without wrapping, which is not correct for the int-specialized forms. Other issues: 1) The overflow check for the intptr case can be streamlined a bit. 2) The logic in AvmCore::increment_d() is incorrect, wrapping at 32-bits for some values representable as intptr on 64-bit platforms. I'm not submitting this patch for review yet, as I think the code can be tightened up a bit further, and a more comprehensive test is needed to make sure that types other than int and uint haven't been inadvertently broken. It is not at all inconceivable that code in the wild is depending on the broken wrapping behavior, both due to ASC and VM issues. On the other hand, increment and decrement are very basic operations, and attempting to version them is scary.
Comment 3•12 years ago
|
||
Comment on attachment 597733 [details] [diff] [review] Handle integer wraparound correctly in increment_i and decrement_i In AvmCore::increment_i(), the expression int32_t(delta) is the same as (delta) since delta is int. (int is always int32, even though theoretically it isn't). I'm not opposed to the extra casting for clarity tho. Swapping delta to the RHS is also just for clarity? ok. All I can really say about the interpreter.cpp changes is that if there *is* a bug, theres almost no chance I would find it. So lets focus on test cases. One important edge case is on 64-bit cpus when you have a kIntptr atom in the 32-52bit range. (you can get such a thing by starting with int.MAX_VALUE and adding those atoms via the fast-paths of OP_add, subtract, etc). I also agree it would be best not to version any of this if we can. forgiveness not permission.
Attachment #597733 -
Flags: feedback?(edwsmith) → feedback+
Assignee | ||
Comment 4•12 years ago
|
||
Test pays particular attention to inflection points. It's a bit of a shotgun, testing many cases at values that aren't particularly interesting, in order to keep the code uniform and systematic.
Assignee | ||
Comment 5•12 years ago
|
||
Also cleans up the code and tightens it up a bit for performance and clarity.
Attachment #599884 -
Flags: review?(edwsmith)
Assignee | ||
Comment 6•12 years ago
|
||
I now realized the significance of Edwin's remark regarding the "important edge case" in comment 3. Large integers like int53_max will be represented in the constant pool as doubles, and will be loaded as double values. The test is predicated on the assumption, however, that each of the test values is represented as an atom in canonical form, represented as kIntptr if possible. The revised patch should assure this if the result of addition is always properly canonicalized, though I'm not sure yet that this is the case for all execution paths, or for the specific patch taken by the test case. See also bug 601426.
Assignee | ||
Updated•12 years ago
|
Attachment #599883 -
Attachment is obsolete: true
Assignee | ||
Updated•12 years ago
|
Attachment #597631 -
Attachment is obsolete: true
Assignee | ||
Comment 7•12 years ago
|
||
Allows testing whether an atom is represented as kIntptrType or not, and to force numeric atoms to be so represented if possible.
Attachment #600226 -
Flags: review?(edwsmith)
Assignee | ||
Comment 8•12 years ago
|
||
Use System.canonicalizeNumber to reliably generate kIntptrType atoms. Increment/Decrement appear to be OK with the revised test, but I'm seeing test failures on x86_64. Curiously, the increment/decrement values look to be correct -- it is the reference additions/subtractions that are wrong. Looks related to signedness -- large positive values are wrapping to small negative values. Investigating...
Assignee | ||
Comment 9•12 years ago
|
||
The SIGN_EXTEND macro was defined incorrectly, resulting in some results wrapping at 53 bits where 54-bit precision was expected. The faulty definition was also mimicked in inline-generated code. See bug 601426 for the fix.
Updated•12 years ago
|
Attachment #599884 -
Flags: review?(edwsmith) → review+
Updated•12 years ago
|
Attachment #600226 -
Flags: review?(edwsmith) → review+
Comment 10•12 years ago
|
||
changeset: 7216:a59cc6992efa user: William Maddox <wmaddox@adobe.com> summary: Bug 700620: Handle integer wraparound correctly in increment_i and decrement_i (r=edwsmith) http://hg.mozilla.org/tamarin-redux/rev/a59cc6992efa
Assignee | ||
Comment 11•12 years ago
|
||
Attachment 600226 [details] [diff] landed previously as part of another fix, see: http://hg.mozilla.org/tamarin-redux/rev/1fb053b49a9f
Assignee | ||
Updated•12 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•