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

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3496 - ICE(cgelem.c, optimizer bug) cast(void *)(x&1)== null.
Summary: ICE(cgelem.c, optimizer bug) cast(void *)(x&1)== null.
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: Other Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: ice-on-valid-code, patch
Depends on:
Blocks:
Reported: 2009年11月11日 09:51 UTC by David Simcha
Modified: 2014年02月15日 13:13 UTC (History)
3 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description David Simcha 2009年11月11日 09:51:33 UTC
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 Don 2009年11月12日 07:17:10 UTC
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 David Simcha 2009年11月13日 08:02:26 UTC
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 Don 2009年11月13日 12:42:02 UTC
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 Don 2009年11月13日 13:17:00 UTC
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 Leandro Lucarella 2009年11月23日 06:48:08 UTC
SVN commit: http://www.dsource.org/projects/dmd/changeset/267 
Comment 6 David Simcha 2009年12月05日 18:33:06 UTC
Fixed 2.037.
Comment 7 Walter Bright 2009年12月06日 00:47:30 UTC
Fixed dmd 1.053 and 2.037


AltStyle によって変換されたページ (->オリジナル) /