Bug 3496 – ICE(cgelem.c, optimizer bug) cast(void *)(x&1)== null.

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
Other
OS
Windows
Creation time
2009-11-11T09:51:00Z
Last change time
2014-02-15T13:13:31Z
Keywords
ice-on-valid-code, patch
Assigned to
nobody
Creator
dsimcha

Comments

Comment #0 by dsimcha — 2009-11-11T09:51:33Z
struct Node { size_t _left; Node* left() { return cast(Node*) (_left & 1); } bool useLeft() { return left is null; } } Result: Internal error: ..\ztc\cgelem.c 3387 This one is really hard to reproduce. If you change this test program in even very small ways, it's no longer reproduced.
Comment #1 by clugdbug — 2009-11-12T07:17:10Z
I can't reproduce this (on Windows) with either D2 or D1. I tried several compiler versions, it compiled correctly in all cases.
Comment #2 by dsimcha — 2009-11-13T08:02:26Z
Didn't realize it at the time, but I've looked into this further. It only happens when you compile w/ -O -inline.
Comment #3 by clugdbug — 2009-11-13T12:42:02Z
Reduced test case. Compile with -O (-inline not required). Not a regression; fails on DMD0.165. bool foo() { int x; return cast(void*) (x & 1) == null; } Internal error: ztc\cgelem.c 3387 Really peculiar thing is that replacing & with | or ^ makes the bug disappear.
Comment #4 by clugdbug — 2009-11-13T13:17:00Z
This assert is actually completely harmless. It's part of a check for if the equality comparison can be reduced to a single byte comparison. This can happen if it's a pointer with all the high bits clear, which includes null. Here are 3 cases which trigger the same bug. bool foo() { int x; // return cast(void*) (x & 1) == null; // Case 1 // return cast(void*) (x & 1) == cast(void *)(2); // Case 2 return cast(bool function()) (x & 1) == null; // Case 3 } ================ PATCH: cgelem.c, line 3387. /* Try to convert to byte/word comparison for ((x & c)==d) when mask c essentially casts x to a smaller type */ if (OPTIMIZER && e1->Eoper == OPand && e1->E2->Eoper == OPconst && (sz = tysize(e2->Ety)) > CHARSIZE) { int op; - assert(tyintegral(e2->Ety)); + assert(tyintegral(e2->Ety) || (e2->Ety == TYnptr)); #if TX86 /* ending up with byte ops in A regs */ if (!(el_tolong(e2) & ~CHARMASK) && !(el_tolong(e1->E2) & ~CHARMASK) ) {
Comment #5 by leandro.lucarella — 2009-11-23T06:48:08Z
Comment #6 by dsimcha — 2009-12-05T18:33:06Z
Fixed 2.037.
Comment #7 by bugzilla — 2009-12-06T00:47:30Z
Fixed dmd 1.053 and 2.037