5809 – [64 bit] wrong code for *p==0, when widening conversion occurs

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5809 - [64 bit] wrong code for *p==0, when widening conversion occurs
Summary: [64 bit] wrong code for *p==0, when widening conversion occurs
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P2 blocker
Assignee: No Owner
URL:
Keywords: pull, wrong-code
Depends on:
Blocks:
Reported: 2011年04月03日 16:28 UTC by Moritz Warning
Modified: 2015年06月09日 05:11 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 Moritz Warning 2011年04月03日 16:28:16 UTC
On x86_64 systems this assert fails because feqrel returns to 0.
assert(feqrel(real.min_normal/8,real.min_normal/17)==3);
Comment 1 Moritz Warning 2011年04月03日 16:28:44 UTC
Here is the link into Phobos:
https://github.com/D-Programming-Language/phobos/blob/master/std/math.d#L3634 
Comment 2 Moritz Warning 2011年04月03日 16:30:07 UTC
It works when a dummy function call is inserted before "if (pd[F.EXPPOS_SHORT] == 0)" inside feqrel.
Comment 3 Don 2011年12月21日 13:02:13 UTC
This sounds like a compiler bug. Does it still fail on 2.057?
Comment 4 Walter Bright 2012年04月23日 17:34:36 UTC
(In reply to comment #3)
> Does it still fail on 2.057?
Works on 32 bit Linux, fails on 64 bit Linux. Test program:
import std.math;
void main() {
 assert(feqrel(real.min_normal/8,real.min_normal/17)==3);
}
Comment 5 Don 2012年05月08日 22:08:29 UTC
Original title: feqrel fails assert in std.math on x86_64 systems
Reduced test case shows it is a backend bug.
The common subexpression *px gets extended to int when calculating b. Inside the assert it is treated as *cast(int *)px, so that it picks up x[1] instead of just x[0]. It seems to only apply to comparisons with 0.
Subtle and disastrous, raising severity to blocker.
void main()
{
 ushort[2] x = void;
 x[0] = 0;
 x[1] = 0x1234;
 ushort *px = &x[0];
 uint b = px[0]; // this causes the next line to fail
 assert(px[0] == 0);
 }
It generates
 cmp	dword ptr -010h[RBP],0
should be word ptr, which doesn't exist in 64bit.
Comment 7 Don 2012年05月10日 07:02:10 UTC
My pull request is wrong. The correct fix is in cgcod.c, line 1795.
In moving to 64 bit, commit 3cdb9f520e0bac17f6da00ef9de86c81e23429aa
made this change:
 c = genc(NULL,0x81 ^ byte,modregrm(2,7,BPRM),
 FLcs,i, FLconst,(targ_uns) 0);
- if (REGSIZE == 4 && sz == 2)
+ if (I32 && sz == 2)
 c->Iflags |= CFopsize;
 }
But this is wrong, it should be 
+ if ((I32 || I64) && sz == 2) 
This code is now in cod3.c, testcse(), line 1795.
Comment 8 Don 2012年05月10日 07:22:16 UTC
Fixed pull request.
https://github.com/D-Programming-Language/dmd/pull/938 
Comment 9 github-bugzilla 2012年05月10日 10:05:33 UTC
Commit pushed to master at https://github.com/D-Programming-Language/dmd
https://github.com/D-Programming-Language/dmd/commit/7c2ea37c476a2d7a289f54cbf1ee0e692d7a69a0
Fix issue 5809: [64 bit] wrong code for *p==0, when widening conversion occurs
Bug was introduced in commit 3cdb9f52, but it never worked on 64bits, so it is
not a regression.


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