← Back to index
|
Original Bugzilla link
Bug 19584 – Illegal optimization: Shift-or -> imul
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-01-14T22:06:28Z
Last change time
2020-03-21T03:56:35Z
Keywords
pull, wrong-code
Assigned to
No Owner
Creator
[email protected]
Comments
Comment #0
by voidstar — 2019-01-14T22:06:28Z
$ dmd --help | head -1 DMD32 D Compiler v2.084.0 $ cat test.d ulong interleave(uint x, uint y) pure { ulong expand(uint a) pure { ulong x = a; x = ((x << 16) | x) & 0x0000ffff0000ffffuL; x = ((x << 8) | x) & 0x00ff00ff00ff00ffuL; x = ((x << 4) | x) & 0x0f0f0f0f0f0f0f0fuL; x = ((x << 2) | x) & 0x3333333333333333uL; x = ((x << 1) | x) & 0x5555555555555555uL; return x; } auto x2 = expand(x); auto y2 = expand(y); assert(!(x2 & (y2 << 1))); return x2 + (y2 << 1); } void main(string[] args) { import std.conv, std.stdio; writeln(interleave(to!uint(args[1]), to!uint(args[2]))); } $ rdmd -O test.d 711 31 264515 $ rdmd test.d 711 31 283327 Oops. Then: $ dmd -g -O test.d Objdump shows: 4022a3: 56 push %esi 4022a4: 57 push %edi 4022a5: 69 ca 01 00 01 00 imul $0x10001,%edx,%ecx 4022ab: ba 01 00 01 00 mov $0x10001,%edx 4022b0: f7 e2 mul %edx 4022b2: 03 d1 add %ecx,%edx 4022b4: 81 e2 ff ff 00 00 and $0xffff,%edx Using imul here to implement '(x << 16) | x' isn't right, because x might be > 16-bits. The -m64 build shows a similar output. (Similar argument for the other imuls to implement the other (x << y) | x operations). You can also see this on an older compiler version with Compiler Explorer:
https://godbolt.org/z/cWBV_z
ldc & gdc do not seem to have this bug.
Comment #1
by voidstar — 2019-01-14T22:14:36Z
Using ^ instead of | works around this particular problem.
Comment #2
by b2.temp — 2019-01-18T17:00:48Z
It's a regression introduced in dmd 2.064. See
https://run.dlang.io/is/fOZ7zl.
Likely culprit commit :
https://github.com/dlang/dmd/pull/2333/files
Comment #3
by sahmi.soulaimane — 2019-05-20T06:16:43Z
Reduced to: ``` void main() { int a = 711; assert(182215 == (a | (a << 8))); assert(182727 == (a * (1 + (1 << 8)))); int b = 31; assert(511 == (b | (b << 4))); assert(527 == (b * (1 + (1 << 4)))); } ```
https://run.dlang.io/is/MjL0NG
Comment #4
by dlang-bot — 2019-06-06T21:31:30Z
@Basile-z created dlang/dmd pull request #9990 "fix issue 19584 - Illegal optimization: Shift-or -> imul" fixing this issue: - fix issue 19584 - Illegal optimization: Shift-or -> imul
https://github.com/dlang/dmd/pull/9990
Comment #5
by dlang-bot — 2019-06-07T06:52:34Z
dlang/dmd pull request #9990 "fix issue 19584 - Illegal optimization: Shift-or -> imul" was merged into stable: - b6d6c2f4c0c21846a40dcd25e7d580c6180536e9 by Basile Burg: fix issue 19584 - Illegal optimization: Shift-or -> imul
https://github.com/dlang/dmd/pull/9990