This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
optimization/6162: gcc 3.0.4: certain i386 asm reloader ice
- From: Kevin Ryde <user42 at zip dot com dot au>
- To: gcc-gnats at gcc dot gnu dot org
- Date: Thu, 04 Apr 2002 10:23:12 +1000
- Subject: optimization/6162: gcc 3.0.4: certain i386 asm reloader ice
>Number: 6162
>Category: optimization
>Synopsis: gcc 3.0.4: certain i386 asm reloader ice
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: unassigned
>State: open
>Class: ice-on-legal-code
>Submitter-Id: net
>Arrival-Date: Wed Apr 03 16:26:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:
>Release: 3.0.4 (Debian testing/unstable)
>Organization:
>Environment:
System: Linux blah 2.2.15 #1 Tue Apr 25 17:13:48 EST 2000 i586 unknown
Architecture: i586
<machine, os, target, libraries (multiple lines)>
host: i386-pc-linux-gnu
build: i386-pc-linux-gnu
target: i386-pc-linux-gnu
configured with: ../src/configure -v --enable-languages=c,c++,java,f77,proto,objc --prefix=/usr --infodir=/share/info --mandir=/share/man --enable-shared --with-gnu-as --with-gnu-ld --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-checking --enable-threads=posix --enable-java-gc=boehm --with-cpp-install-dir=bin --enable-objc-gc i386-linux
>Description:
On i386, a certain slightly convoluted combination of variables and
asm blocks provokes an ICE from gcc under "-O -fomit-frame-pointer".
>How-To-Repeat:
The file foo.c below (which has been through the preprocessor
already), compiled with
gcc-3.0 -O -fomit-frame-pointer -c foo.c
produces
foo.c: In function `__gmpn_divrem_1':
foo.c:219: Unrecognizable insn:
(insn 399 662 401 (parallel[
(set (reg/v:SI 6 ebp [89])
(asm_operands:SI ("addl %5,%1
adcl %3,%0") ("=r") 0[
(mem:SI (plus:SI (reg/f:SI 7 esp)
(const_int 48 [0x30])) 0)
(reg/v:SI 6 ebp [93])
(reg/v:SI 2 ecx [90])
(reg/v:SI 4 esi [78])
]
[
(asm_input:SI ("%0"))
(asm_input:SI ("g"))
(asm_input:SI ("%1"))
(asm_input:SI ("g"))
] ("foo.c") 172))
(set (reg/v:SI 2 ecx [90])
(asm_operands:SI ("addl %5,%1
adcl %3,%0") ("=&r") 1[
(mem:SI (plus:SI (reg/f:SI 7 esp)
(const_int 48 [0x30])) 0)
(reg/v:SI 6 ebp [93])
(reg/v:SI 2 ecx [90])
(reg/v:SI 4 esi [78])
]
[
(asm_input:SI ("%0"))
(asm_input:SI ("g"))
(asm_input:SI ("%1"))
(asm_input:SI ("g"))
] ("foo.c") 172))
(clobber (reg:QI 19 dirflag))
(clobber (reg:QI 18 fpsr))
(clobber (reg:QI 17 flags))
] ) -1 (insn_list 390 (insn_list 390 (nil)))
(nil))
foo.c:219: Internal compiler error in reload_cse_simplify_operands, at reload1.c:8364
For what it's worth, this was an experimental GMP division routine,
but only a work-in-progress version, so the code isn't supposed to
work or do anything useful, but I think it's syntactically correct
(since it seems to compile fine if either of -O or
-fomit-frame-pointer is omitted).
--=-=-=
Content-Type: text/x-csrc
Content-Disposition: attachment; filename=foo.c
typedef unsigned * mp_ptr;
typedef const unsigned * mp_srcptr;
void __gmpn_tdiv_qr (mp_ptr, mp_ptr, long, mp_srcptr, long, mp_srcptr, long);
void __gmp_assert_fail (const char *filename, int linenum, const char *expr)
__attribute__ ((noreturn));
unsigned
__gmpn_divrem_1 (mp_ptr qp, long xsize,
mp_srcptr ap, long size, unsigned d)
{
long total_size;
long i;
unsigned dinvh, dinvl;
unsigned r;
do {
if (!(xsize >= 0))
__gmp_assert_fail ("divrem_1_two_ice.c", 179, "xsize >= 0");
} while (0);
do {
if (!(size >= 0))
__gmp_assert_fail ("divrem_1_two_ice.c", 180, "size >= 0");
} while (0);
do {
if (!(d != 0))
__gmp_assert_fail ("divrem_1_two_ice.c", 181, "d != 0");
} while (0);
do {
if (!(((qp+xsize) == (ap) || ! ((qp+xsize) + (size) > (ap) && (ap) + (size) > (qp+xsize)))))
__gmp_assert_fail ("divrem_1_two_ice.c", 183, "((qp+xsize) == (ap) || ! ((qp+xsize) + (size) > (ap) && (ap) + (size) > (qp+xsize)))");
} while (0);
total_size = size + xsize;
if (total_size == 0)
return 0;
qp += (total_size - 1);
if ((d & ((~ (unsigned) 0) ^ ((~ (unsigned) 0) >> 1))) != 0)
{
do {
unsigned a[4];
unsigned q[3];
unsigned d_array[2];
unsigned r_dummy[2];
do {
if (!(((d) & ((~ (unsigned) 0) ^ ((~ (unsigned) 0) >> 1))) != 0))
__gmp_assert_fail ("divrem_1_two_ice.c", 193, "((d) & ((~ (unsigned) 0) ^ ((~ (unsigned) 0) >> 1))) != 0");
} while (0);
a[0] = (~ (unsigned) 0);
a[1] = (~ (unsigned) 0);
a[2] = (~ (unsigned) 0);
a[3] = (~ (unsigned) 0);
d_array[0] = 0L;
d_array[1] = d;
__gmpn_tdiv_qr (q, r_dummy, (long) 0, a, (long) 4, d_array, (long) 2);
do {
if (!(q[2] == 1))
__gmp_assert_fail ("divrem_1_two_ice.c", 193, "q[2] == 1");
} while (0);
dinvl = q[0];
dinvh = q[1];
} while (0);
i = size-1;
r = 0;
if (i > 0)
{
r = ap[i];
if (r < d)
i--;
}
while (i >= 1)
{
do {
unsigned _n2h = (r);
unsigned _n2l = (ap[i]);
unsigned _n10h = (ap[i-1]);
unsigned _d = (d);
unsigned _n1, _nadjh, _sumh, _suml, _q1h, _q1l, _mask, _r;
unsigned _x3, _x2, _x1, _x0;
_n1 = _n10h >> ((8*4) - 1);
_nadjh = _n10h + (-_n1 & _d);
__asm__ ("subl %5,%1\n\tsbbl %3,%0"
: "=r" ((unsigned)(_sumh)), "=&r" ((unsigned)(_suml))
: "0" ((unsigned)(_n2h)), "g" ((unsigned)(0)),
"1" ((unsigned)(_n2l)), "g" ((unsigned)(_n1)));
do {
unsigned _xh = (dinvh);
unsigned _xl = (dinvl);
unsigned _yh = (_sumh);
unsigned _yl = (_suml);
unsigned _mh, _ml;
__asm__ ("mull %3"
: "=a" (_x0), "=d" (_x1)
: "%0" ((unsigned)(_xl)),
"rm" ((unsigned)(_yl)));
__asm__ ("mull %3"
: "=a" (_x2), "=d" (_x3)
: "%0" ((unsigned)(_xh)), "rm" ((unsigned)(_yh)));
__asm__ ("mull %3"
: "=a" (_ml), "=d" (_mh)
: "%0" ((unsigned)(_xh)), "rm" ((unsigned)(_yl)));
do {
unsigned _c1, _s0;
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned)(_c1)), "=&r" ((unsigned)(_s0))
: "%0" ((unsigned)(0)), "g" ((unsigned)(0)),
"%1" ((unsigned)(_x1)), "g" ((unsigned)(_ml)));
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned)(_x3)), "=&r" ((unsigned)(_x2))
: "%0" ((unsigned)(_x3)), "g" ((unsigned)(0)),
"%1" ((unsigned)(_x2)), "g" ((unsigned)(_mh)));
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned)(_x3)), "=&r" ((unsigned)(_x2))
: "%0" ((unsigned)(_x3)), "g" ((unsigned)(0)),
"%1" ((unsigned)(_x2)), "g" ((unsigned)(_c1)));
(_x1) = _s0;
} while (0);
__asm__ ("mull %3"
: "=a" (_ml), "=d" (_mh)
: "%0" ((unsigned)(_xl)), "rm" ((unsigned)(_yh)));
do {
unsigned _c1, _s0;
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned)(_c1)), "=&r" ((unsigned)(_s0))
: "%0" ((unsigned)(0)), "g" ((unsigned)(0)),
"%1" ((unsigned)(_x1)), "g" ((unsigned)(_ml)));
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned)(_x3)), "=&r" ((unsigned)(_x2))
: "%0" ((unsigned)(_x3)), "g" ((unsigned)(0)),
"%1" ((unsigned)(_x2)), "g" ((unsigned)(_mh)));
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned)(_x3)), "=&r" ((unsigned)(_x2))
: "%0" ((unsigned)(_x3)), "g" ((unsigned)(0)),
"%1" ((unsigned)(_x2)), "g" ((unsigned)(_c1)));
(_x1) = _s0;
} while (0);
} while (0);
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned) (_q1h)),
"=&r" ((unsigned) (_q1l))
: "%0" ((unsigned) (_n2h)),
"g" ((unsigned) (_x3)),
"%1" ((unsigned) (_n2l)),
"g" ((unsigned) (_x2)));
__asm__ ("addl %5,%1\n\tadcl %3,%0"
: "=r" ((unsigned)(_q1h)), "=&r" ((unsigned)(_q1l))
: "%0" ((unsigned)(_q1h)), "g" ((unsigned)(0)),
"%1" ((unsigned)(_q1l)), "g" ((unsigned)(1)));
__asm__ ("mull %3"
: "=a" (_x1), "=d" (_x2)
: "%0" ((unsigned)(_q1l)), "rm" ((unsigned)(_d)));
_x2 += _q1h * _d;
__asm__ ("subl %5,%1\n\tsbbl %3,%0"
: "=r" ((unsigned)(_mask)), "=&r" ((unsigned)(_r))
: "0" ((unsigned)(_n2l)), "g" ((unsigned)(_x2)),
"1" ((unsigned)(_n10h)), "g" ((unsigned)(_x1)));
do {
if (!(_mask == 0 || _mask == (~ (unsigned) 0)))
__gmp_assert_fail ("divrem_1_two_ice.c", 243, "_mask == 0 || _mask == (~ (unsigned) 0)");
} while (0);
(r) = _r + (_mask & _d);
__asm__ ("subl %5,%1\n\tsbbl %3,%0"
: "=r" ((unsigned)(qp[0])), "=&r" ((unsigned)(qp[-1]))
: "0" ((unsigned)(_q1h)), "g" ((unsigned)(0)),
"1" ((unsigned)(_q1l)), "g" ((unsigned)(-_mask)));
} while (0);
qp -= 2;
i -= 2;
}
}
else
{
r = 0;
}
return r;
}
--=-=-=--
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
--=-=-=