[Issue 16217] New: Wrong code with -O -inline on function with right shift
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Wed Jun 29 01:05:24 PDT 2016
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 at puremagic.com
Reporter: dbugz at 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.
--
More information about the Digitalmars-d-bugs
mailing list