1081 – with using real and -O option, dmd generate bug code

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 1081 - with using real and -O option, dmd generate bug code
Summary: with using real and -O option, dmd generate bug code
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 All
: P2 normal
Assignee: Walter Bright
URL: http://www.geocities.jp/s180m/bug_opt...
Keywords:
Depends on:
Blocks:
Reported: 2007年03月27日 02:21 UTC by s180m
Modified: 2014年02月16日 15:23 UTC (History)
0 users

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 s180m 2007年03月27日 02:21:21 UTC
//dmd -release -inline -O で間違った動作をする。
//-Oを外すか、realをプログラムから追放すると、正しい動作。
import std.file;
import std.math;
import std.c.windows.windows;
import std.c.stdlib;
import std.outofmemory;
alias real Real;
align(1)
struct BGR24 {
 ubyte blue , green , red;
 const BGR24 Gray = {0xc0 , 0xc0 , 0xc0};
}
int clamp(int value,int min,int max){
 if(value<min) return min;
 if(value>max) return max;
 return value;
}
BITMAPINFOHEADER* transform_(BITMAPINFOHEADER* src,Real angle){
 int width = src.biWidth;assert(0==width % 4);///@note bmpのpaddingを考慮していない。
 int height = abs(src.biHeight);
 BGR24* srcLines = cast(BGR24*)&src[1];
 BITMAPINFOHEADER* result = cast(BITMAPINFOHEADER*)(new ubyte[40+width*3*height]);
 *result = *src;
 BGR24* dstLines = cast(BGR24*)&result[1];
 int width16 = width<<16;
 int height16 = height<<16;
 Coordinate coord;
 coord.initY(src,angle);
 for(int j;j<height;j++){
 coord.initX();
 for(int i;i<width;i++){
 BGR24 pixel = BGR24.Gray;
 if( (0<=coord.sa.x) && (0<=coord.sa.y) && (coord.sa.x<width16) && (coord.sa.y<height16) ) {
 pixel = srcLines[(coord.sa.y>>16) * width + (coord.sa.x>>16)];
 }
 dstLines[j * width + i] = pixel;
 coord.stepX();
 }
 coord.stepY();
 }
 return result;
}
BITMAPINFOHEADER* transform_L2(BITMAPINFOHEADER* src,Real angle){
 int width = src.biWidth;assert(0==width % 4);///@note bmpのpaddingを考慮していない。
 int height = abs(src.biHeight);
 BGR24* srcLines = cast(BGR24*)&src[1];
 BITMAPINFOHEADER* result = cast(BITMAPINFOHEADER*)(new ubyte[40+width*3*height]);
 *result = *src;
 BGR24* dstLines = cast(BGR24*)&result[1];
 Coordinate coord;
 coord.initY(src,angle);
 for(int j;j<height;j++){
 coord.initX();
 for(int i;i<width;i++){
 Info info;
 POINT pos;
 pos.x = coord.sa.x>>16;
 pos.y = coord.sa.y>>16;
 int fx_= (coord.sa.x & 0xffff) + 0x10000;
 int fy = (coord.sa.y & 0xffff) + 0x10000;
 for(int jj=pos.y-2;jj<pos.y+2;jj++,fy-=0x10000){
 long w2 = cast(long)Lanczos2[fy];
 for(int ii=pos.x-2,fx=fx_;ii<pos.x+2;ii++,fx-=0x10000){
 long weight = cast(long)Lanczos2[fx] * w2;
 info.step1(weight);
 if( (0<=ii) && (0<=jj) && (ii<width) && (jj<height) ){
 info.step2(srcLines[jj * width + ii],weight);
 }
 }
 }
 dstLines[j * width + i] = info.getPixel;
 coord.stepX();
 }
 coord.stepY();
 }
 return result;
}
private struct Coordinate {
 POINT dx,dy,sl,sa;
 void initY(BITMAPINFOHEADER* src,Real angle) {
 dx.x = cast(int)( cos(angle) * 65536.);
 dx.y = cast(int)(-sin(angle) * 65536.);
 dy.x =-dx.y;
 dy.y = dx.x;
 sl.x = 0;
 sl.y = 0;
 }
 void initX(){sa = sl;}
 void stepX(){sa.x += dx.x;sa.y += dx.y;}
 void stepY(){sl.x += dy.x;sl.y += dy.y;}
}
private struct Info {
 alias BGR24 T;
 long b,g,r,d;
 void step1(long weight){}
 void step2(T pixel,long weight){
 b+=pixel.blue * weight;
 g+=pixel.green * weight;
 r+=pixel.red * weight;
 d+=weight;
 }
 T getPixel(){
 if(0==d) return T.Gray;
 T result;
 result.blue = clamp(b/d,0,255);
 result.green = clamp(g/d,0,255);
 result.red = clamp(r/d,0,255);
 return result;
 }
}
abstract final class Lanczos2 {
private:
 static int* s_table;
 static this(){
 s_table = cast(int*)malloc(int.sizeof * (2<<16));
 if(! s_table) _d_OutOfMemory();
 Real t =0;
 for(int i=0;i<2<<16;i++){
 t += 1./65536.;
 s_table[i] = cast(int)round( 65536.*sin(PI*t)*sin(PI/2.*t)/((PI*PI/2.)*t*t) );
 }
 s_table[0] = 1<<16;
 }
public:
 static int opIndex(int a) {
 if((a <= -2<<16) || (a >= 2<<16)) return 0;
 if(a<0) a=-a;
 assert((0<=a)&&(a<2<<16));
 return s_table[a];
 }
}
void main(){
 ubyte[] src = cast(ubyte[])read("a.bmp");
 BITMAPINFOHEADER* dst = transform_L2(cast(BITMAPINFOHEADER*)&src[14],PI/10.);
 write("a_out.bmp",src[0..14] ~ (cast(ubyte*)dst)[0..src.length-14]);
}
Comment 1 Walter Bright 2007年03月29日 19:13:51 UTC
This isn't reproducible, as it tries to read a.map, so nothing can be done with it as it stands. Also, can you describe what is going on, and perhaps cut it down to a smaller example?
Comment 2 s180m 2007年03月29日 20:31:36 UTC
(In reply to comment #1)
> This isn't reproducible, as it tries to read a.map, so nothing can be done with
> it as it stands. Also, can you describe what is going on, and perhaps cut it
> down to a smaller example?
> 
I uploaded these files.
The first one is buggy.
The 2nd and the 3rd were able to be evaded. 
http://www.geocities.jp/s180m/bug_opt.zip
http://www.geocities.jp/s180m/bug_opt_double.zip
http://www.geocities.jp/s180m/bug_opt_release_inline.zip
Comment 3 s180m 2007年03月29日 21:28:40 UTC
// a small example
import std.c.stdlib;
import std.math;
import std.outofmemory;
abstract final class Lanczos2 {
private:
 static int* s_table;
 static this(){
 s_table = cast(int*)malloc(int.sizeof * (2<<16));
 if(! s_table) _d_OutOfMemory();
 real t = 0.;
 for(int i=0;i<2<<16;i++){
 t += 1./65536.;
 s_table[i] = cast(int)round( 65536.*sin(PI*t)*sin(PI/2.*t)/((PI*PI/2.)*t*t) );
 }
 s_table[0] = 1<<16;
 }
public:
 static int opIndex(int a) {
 if((a <= -2<<16) || (a >= 2<<16)) return 0;
 if(a<0) a=-a;
 assert((0<=a)&&(a<2<<16));
 return s_table[a];
 }
}
void main(){
 int d;
 for(int i=-0x1abcd;i<0x20000;i+=0x10000){
 printf("%8x + %8x ",d,Lanczos2[i]);
 d += Lanczos2[i];
 printf(" = %8x\n",d);
 }
 if(0==d) printf("error A\n");
}
/**
 * >dmd -release -inline bug_opt.d
 * >bug_opt2.exe
 * 0 + fffff81e = fffff81e
 * fffff81e + 5606 = 4e24
 * 4e24 + cb79 = 1199d
 * 1199d + ffffea0f = 103ac
 *
 *
 * >dmd -release -inline -O bug_opt.d
 * >bug_opt2.exe
 * 0 + 80000000 = 80000000
 * 80000000 +たす 80000000 = 0
 * 0 + 80000000 = 80000000
 * 80000000 +たす 80000000 = 0
 * error A
 *
 */
Comment 4 Walter Bright 2007年03月30日 04:36:01 UTC
Thanks for the succint example. I found the problem, and a fix will go out with the next update.
Comment 6 Walter Bright 2007年04月11日 22:01:38 UTC
Fixed dmd 1.011


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