Bug 8796 – Optimizer bug on 64bit: *p++=1 where p is a parameter

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-10-10T14:13:00Z
Last change time
2015-06-09T05:11:59Z
Keywords
wrong-code
Assigned to
nobody
Creator
dmitry.olsh

Comments

Comment #0 by dmitry.olsh — 2012-10-10T14:13:18Z
Uncovered while doing a re-write for std.array.insertInPlace. It got caught by pull auto-tester. Sample: import std.conv, std.utf; void insertInPlace(T, U...)(ref T[] array, size_t pos, U stuff) { {// mutable, can do in place //helper function: re-encode dchar to Ts and store at *ptr static T* putDChar(T* ptr, dchar ch) { static if(is(T == dchar)) { *ptr++ = ch; return ptr; } else { T[dchar.sizeof/T.sizeof] buf; size_t len = encode(buf, ch); final switch(len) { static if(T.sizeof == char.sizeof) { case 4: ptr[3] = buf[3]; goto case; case 3: ptr[2] = buf[2]; goto case; } case 2: ptr[1] = buf[1]; goto case; case 1: ptr[0] = buf[0]; } ptr += len; return ptr; } } immutable oldLen = array.length; size_t to_insert = 0; foreach (i, E; U) to_insert += codeLength!T(stuff[i]); array.length += to_insert; auto ptr = array.ptr + pos; foreach (i, E; U) { static if(is(E : dchar)) { ptr = putDChar(ptr, stuff[i]); } else { foreach (dchar ch; stuff[i]) ptr = putDChar(ptr, ch); } } assert(ptr == array.ptr + pos + to_insert, text(ptr - array.ptr, " vs ",pos+ to_insert )); } } void main() { auto l = "hello"d.dup; auto r = " વિશ્વ".dup; l.insertInPlace(0, r); } Compiled as dmd -O atest.d It fails with: [email protected](75): 0 vs 6 Compiled without -O it doesn't fail. It also works fine in 32 bits. Tested with dmd 2.061 from github. Commit a1287bd0b1931917f4e43b5e2d7b997f0d60adf6.
Comment #1 by clugdbug — 2012-11-05T11:43:22Z
Reduced test case (applies to postfix ++ and --): int* wrong8796(int* p) { *p++ = 1; return p; } // The wrong code is generated in the function above, main() is just to demonstrate void main() { int [3] arr; int * q = arr.ptr; q = wrong8796(q); assert(q != arr.ptr); } Without -O, wrong8796() compiles to: push RBP mov RBP,RSP sub RSP,8 mov -8[RBP],RDI mov RAX,-8[RBP] add qword ptr -8[RBP],4 mov dword ptr [RAX],1 mov RAX,-8[RBP] leave ret With -O: push RBP mov RBP,RSP mov RAX,RDI mov qword ptr [RAX],1 add RAX,4 mov RAX,RDI <---- wrong pop RBP ret
Comment #2 by github-bugzilla — 2012-12-10T23:45:40Z
Commit pushed to dmd-1.x at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/5b7620ea1c664ac7686070a8493edcd34d9929fc fix Issue 8796 - Optimizer bug on 64bit: *p++=1 where p is a parameter
Comment #3 by github-bugzilla — 2012-12-10T23:45:52Z
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/de67647952432b11e61d7f79129a4f9d7f00e37a fix Issue 8796 - Optimizer bug on 64bit: *p++=1 where p is a parameter
Comment #4 by bugzilla — 2012-12-10T23:58:07Z
This bug has lurked for a very long time, and was on all platforms.