Bug 11689 - g++3.3 emits un-assembleable code for k6 architecture
Summary: g++3.3 emits un-assembleable code for k6 architecture
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.3.1
: P2 normal
Target Milestone: 3.3.2
Assignee: Eric Botcazou
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2003-07-27 21:38 UTC by thor
Modified: 2003-09-08 06:51 UTC (History)
2 users (show)

See Also:
Host: k6-pc-linux-gnu
Target: k6-pc-linux-gnu
Build: k6-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2003-07-27 22:07:40


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description thor 2003-07-27 21:38:29 UTC
Save the following code as foo.cpp:

/* snip */
class JKeeper {
public:
  unsigned long a0;
};

class EBCOTLut : public JKeeper {
  unsigned char a1[1<<8];   
  unsigned char a2[1<<8];
  unsigned char a3[1<<8];
  long          a4[1<<9];
public:
  EBCOTLut(void);
};

EBCOTLut::EBCOTLut(void)
{
  unsigned char inter[36];   // intermediate lookup table;
  unsigned long i;
  for(i=0;i<36;i++) {
    inter[i] = 0;
  }
  for(i=1;i<16;i++) {
    a1[i | (1<<7)] = 8<<1;
    a1[i | (1<<6)] = 8<<1;
  }
  for(i=0;i < ((1<<9)-1);i++) {
    int ds = (i>>0) & 0x01;    // significance of DOWN
    int us = (i>>1) & 0x01;    // significance of UP
    int rs = (i>>2) & 0x01;    // significance of RIGHT
    int ls = (i>>3) & 0x01;    // significance of LEFT
    int dn = (i>>5) & 0x01;    // sign of DOWN
    int un = (i>>6) & 0x01;    // sign of UP
    int rn = (i>>7) & 0x01;    // sign of RIGHT
    int ln = (i>>8) & 0x01;    // sign of LEFT
    int h,v;                   // h and v as in the VM description

    h = ls*(1-ln*2) + rs*(1-2*rn);
    v = us*(1-un*2) + ds*(1-2*dn);
    h = (h >= -1)?(h):(-1);
    v = (v >= -1)?(v):(-1);
    h = (h <=  1)?(h):(1);
    v = (v <=  1)?(v):(1);
    a2[i] = inter[((h+1)<<3) | (v+1)];
    a3[i] = inter[((h+1)<<3) | (v+1)] & (unsigned char)(~1);
  }
  for(i=0;i< 1<<9; i++) {
    a4[i]    = 2*(i-(1<<(9-1)))*(i-(1<<(9-1))) - 
      ((i< (1<<(9-1)))?
       (2*(i-(1<<(9-2)))*(i-(1<<(9-2)))):
       (2*(i-(3<<(9-2)))*(i-(3<<(9-2)))));

  }
}
/* snip */

Then compile as follows:

g++-3.3 -c -O3 -funroll-loops -mcpu=k6 -fomit-frame-pointer foo.cpp

The result of this is:

/tmp/ccDJ3xI4.s: Assembler messages:
/tmp/ccDJ3xI4.s:85: Error: value of ffffffffffffff7a too large for field of 1
bytes at 000000000000010b
/tmp/ccDJ3xI4.s:355: Error: value of ffffffffffffff7a too large for field of 1
bytes at 00000000000004ab

Thus, the gcc compiler generates unsuitable code for the assembler.
The offending assembly lines contain a .loop statement with a branch target that
seems likely to be too large.
Comment 1 Andrew Pinski 2003-07-27 22:07:39 UTC
I can confirm this on 3.3.1 (20030707).  On the mainline, the unroller is useless for the "doloop" 
optimization so it is not reproducable there.
In 3.2.3 or 3.0.4 or 2.95.3, the "doloop" optimization does not happen for some reason.


The workaround for 3.3 is to use -fno-branch-count-reg.
Comment 2 Andrew Pinski 2003-09-01 03:36:07 UTC
*** Bug 12116 has been marked as a duplicate of this bug. ***
Comment 3 Eric Botcazou 2003-09-01 08:26:17 UTC
I will shortly be investigating.
Comment 4 CVS Commits 2003-09-08 06:41:53 UTC
Subject: Bug 11689

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	ebotcazou@gcc.gnu.org	2003-09-08 06:41:50

Modified files:
	gcc            : ChangeLog 
	gcc/config/i386: i386.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/opt: longbranch2.C 

Log message:
	PR target/11689
	* config/i386/i386.c (memory_address_length): Fix computation when
	the base is esp or ebp.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.1001&r2=2.1002
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/i386.c.diff?cvsroot=gcc&r1=1.599&r2=1.600
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3038&r2=1.3039
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/longbranch2.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 6 Eric Botcazou 2003-09-08 06:51:00 UTC
See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00357.html