digitalmars.D.bugs - [Issue 16217] New: Wrong code with -O -inline on function with right
- via Digitalmars-d-bugs (50/50) Jun 29 2016 https://issues.dlang.org/show_bug.cgi?id=16217
https://issues.dlang.org/show_bug.cgi?id=16217 Issue ID: 16217 Summary: Wrong code with -O -inline on function with right shift Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: dbugz joakim.fea.st There was a recent off-by-one bug in Phobos, where toChars was incorrectly slicing its result: https://issues.dlang.org/show_bug.cgi?id=16192 It ended up right-shifting by a negative number and I wondered why dmd didn't warn about this. I see now that static analysis or a runtime check is not done with such functions, so the compiler doesn't know and the binary can't tell you what went wrong at runtime. However, when creating an equivalent test to see what's going on, I seem to have stumbled on another inlining/optimization combo bug in dmd. Here's the code I wrote to mimic the toChars issue linked above: int check_shift(int x) { return 16 >>> ((2 - x) * 4);} unittest { assert(check_shift(3) == 16); //assert(( 16 >>> (2-3) * 4) == 16); } If the second assert isn't commented out, dmd always evaluates that expression at compile-time and gives this error: shift.d(5): Error: shift by -4 is outside the range 0..31 If it's left commented out and the file is compiled with this command, ./2.071.1/linux/bin64/dmd -O -unittest -main shift.d the resulting binary asserts at runtime on line 4, ie the first assert. If I compile again with inlining, ./2.071.1/linux/bin64/dmd -O -inline -unittest -main shift.d the test passes, because the entire unittest block is "optimized" out, ie it's simply removed from the resulting assembly: 0000000000422b80 <_D5shift14__unittestL2_1FZv>: 422b80: 50 push %rax 422b81: 58 pop %rax 422b82: c3 retq 422b83: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) This doesn't happen with inlining alone, the binary asserts there. The problem is reproducible with dmd 2.063.2 on linux/x64 also, which is the oldest dmd I had lying around. Fwiw, ldc 1.0.0 for linux/x64 also passes the test if optimization and inlining are enabled. --
Jun 29 2016