www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1081] New: with using real and -O option, dmd generate bug code

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081

           Summary: with using real and -O option, dmd generate bug code
           Product: D
           Version: unspecified
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: s180m yahoo.co.jp


//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]);
}


-- 
Mar 27 2007
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081






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?


-- 
Mar 29 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081







 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 --
Mar 29 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081






// 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
 *
 */


-- 
Mar 29 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081






Thanks for the succint example. I found the problem, and a fix will go out with
the next update.


-- 
Mar 30 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081


thomas-dloop kuehne.cn changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         OS/Version|Windows                     |All
            Version|unspecified                 |1.010





Added to DStress as
http://dstress.kuehne.cn/run/o/odd_bug_14_A.d
http://dstress.kuehne.cn/run/o/odd_bug_14_B.d
http://dstress.kuehne.cn/run/o/odd_bug_14_C.d


-- 
Mar 31 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081


s180m yahoo.co.jp changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED




-- 
Apr 11 2007
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1081






Fixed dmd 1.011


-- 
Apr 11 2007