Bug 17940 – bool function parameters loaded from struct sometimes miscompiled with -O

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2017-10-26T14:31:36Z
Last change time
2017-12-18T22:56:33Z
Assigned to
No Owner
Creator
Eugene Wissner

Comments

Comment #0 by belka — 2017-10-26T14:31:36Z
Code (test.d): struct Array { long length, ptr; } struct Struct { bool b1 = true, b2; } void fun(Array arr, int, int) { if (arr.length != 0) asm { int 3; } } void fn(Struct* str) { Array arr; if (!str) return; if (str.b1) { fun(arr, str.b2, 0); } if (str.b1) { fun(arr, str.b1, 0); } } void main() { Struct s; fn(&s); } Then: dmd -O test.d && ./test causes "Trace/breakpoint trap"
Comment #1 by default_357-line — 2017-10-26T14:53:08Z
Simplified a bit: struct Array { long length, ptr; } struct Struct { bool b = true; } void fun1(int) { } void fun2(Array arr, int, int) { assert(!arr.length); } void fn(Struct* str) { Array arr; if (!str) return; if (str) { fun1(str.b); } if (str.b) { fun2(arr, str.b, 0); } } void main() { Struct s; fn(&s); }
Comment #2 by default_357-line — 2017-10-26T16:10:57Z
Hah! It tries to reload the cse into ESI, but since that's a 1-byte operation (since bool), it actually becomes a move to DH. ESI is not even reachable with 1-byte ops, because those register values were used to address high regs. So for reg8 opcodes like 0x8A, code->setReg should assert on reg & 4. How to actually fix this though, no idea.
Comment #3 by default_357-line — 2017-10-27T15:00:41Z
Comment #4 by github-bugzilla — 2017-11-02T09:59:44Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/87cd61e4c4aca33254bacb2af735433193a51039 fix issue 17940 When generating a 1-byte mov cse on x86_64, handle the REX flag after setReg, instead of when the instruction is first created, since that's when we know if we need it. https://github.com/dlang/dmd/commit/89b0af132529d4635717fd4b16ffc300056dd1b9 Merge pull request #7252 from FeepingCreature/master fix issue 17940 - always set REX for 1-byte CSE moves on x86_64 merged-on-behalf-of: Walter Bright <[email protected]>
Comment #5 by github-bugzilla — 2017-12-18T22:56:33Z