Bug 5672 – ICE(cod2.c): incorrect optimization of (long &1) == 1

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2011-03-01T06:12:00Z
Last change time
2015-06-09T05:12:00Z
Keywords
ice-on-valid-code
Assigned to
nobody
Creator
spam

Comments

Comment #0 by spam — 2011-03-01T06:12:32Z
enum Foo : ulong //remove the :ulong and the internal error is gone { baa = 0B_001, } void bitfieldToStrings(T)(T _val) { string[] res; foreach(mem; __traits(allMembers, T)) { if( (_val & 1) == 1 ) { res ~= "foo"; } } } void main(string[] argv) { Foo bar; bitfieldToStrings(bar); } Just happens when compiled with : dmd main.d -O Tested with dmd 2.051 and 2.052
Comment #1 by clugdbug — 2011-03-01T07:38:38Z
Reduced test case: void foo5672() {} void bug5672(long v) { if( (v & 1) == 1 ) { foo5672(); } } Prehistoric bug. Same ICE on DMD 0.140.
Comment #2 by clugdbug — 2011-03-01T17:06:17Z
Completely reduced test case: ---- bool bug5672(long v) { return (v & 1) == 1; } ---- It's happening because in cgelem.c, elcmp(), around line 3350, bool = (long & 1) == 1; gets optimized into bool = long & 1; Setting the new size of the long expression isn't done correctly.
Comment #3 by clugdbug — 2011-03-02T00:13:01Z
Actually I think the problem is in ellngsht. The (long&1)==1 optimisation does cast(bool)cast(short)cast(int)((e & 1)==1) and assumes that it'll get optimised to (cast(bool)e) & 1. But it doesn't. The optimiser does a very poor job in a case like this: bool foo(long v) { return v&1; } It generates this: mov EAX,4[ESP] mov EDX,8[ESP] and EAX,1 xor EDX,EDX or EDX,EAX jne L17 xor EAX,EAX jmp short L1C L17: mov EAX,1 L1C: ret 8 That's terrible code! It should just do: mov EAX, 4[ESP] and EAX, 1 ret 8
Comment #4 by bugzilla — 2011-03-02T14:57:52Z