[PR42536] crash trying to build portable .net

Bug #472056 reported by Neil Silverman
22
This bug affects 3 people
Affects Status Importance Assigned to Milestone
gcc
Confirmed
Medium
gcc-4.4 (Ubuntu)
Triaged
Medium
Unassigned

Bug Description

Binary package hint: gcc-4.4

cvm_call.c: In function '_ILCVMInterpreter':
cvm_call.c:2083: warning: pointer targets in passing argument 1 of 'ILInterlockedIncrement' differ in signedness
../support/interlocked_x86.h:53: note: expected 'ILInt32 *' but argument is of type 'ILUInt32 *'
cvm.c:579: warning: optimization may eliminate reads and/or writes to register variables
cvm.c:579: warning: optimization may eliminate reads and/or writes to register variables
cvm.c:579: warning: optimization may eliminate reads and/or writes to register variables
cvm.c:889: error: unable to find a register to spill in class 'GENERAL_REGS'
cvm.c:889: error: this is the insn:
(insn 11555 11554 11556 864 cvm_ptr.c:66 (set (mem:DI (plus:SI (plus:SI (mult:SI (reg:SI 2717 [ D.18599 ])
                        (const_int 8 [0x8]))
                    (reg/f:SI 2720 [ tempptr.3565 ]))
                (const_int 4 [0x4])) [5 S8 A64])
        (reg:DI 8052)) 88 {*movdi_2} (expr_list:REG_DEAD (reg:DI 8052)
        (expr_list:REG_DEAD (reg/f:SI 2720 [ tempptr.3565 ])
            (expr_list:REG_DEAD (reg:SI 2717 [ D.18599 ])
                (nil)))))
cvm.c:889: confused by earlier errors, bailing out
Preprocessed source stored into /tmp/cceU3FUr.out file, please attach this to your bugreport.
make[2]: *** [cvm.o] Error 1
make[2]: Leaving directory `/home/nsilverman/Downloads/dotgnu/pnet-0.8.0/engine'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/nsilverman/Downloads/dotgnu/pnet-0.8.0/engine'
make: *** [all-recursive] Error 1

ProblemType: Crash
Architecture: i386
Date: Mon Nov 2 21:16:04 2009
DistroRelease: Ubuntu 9.10
ExecutablePath: /usr/lib/gcc/i486-linux-gnu/4.4.1/cc1
NonfreeKernelModules: nvidia
Package: cpp-4.4 4.4.1-4ubuntu8
ProcVersionSignature: Ubuntu 2.6.31-14.48-generic
SourcePackage: gcc-4.4
Uname: Linux 2.6.31-14-generic i686

Revision history for this message
Neil Silverman (silvermanneil) wrote :
Revision history for this message
In , Debian GCC maintainers (debian-gcc) wrote :

seen with 20091228 trunk and 4.4 branch on i486-linux-gnu, not seen with 4.3 branch (opening new report, because PR39431 is fixed for 4.4 and 4.5). Adding -fomit-frame-pointer avoids the ice.

  Matthias

$ /usr/lib/gcc-snapshot/bin/gcc -g -O2 -fno-gcse -fno-inline-functions -fno-unit-at-a-time -fstack-protector -c cvm.i
cvm.c: In function '_ILCVMInterpreter':
cvm.c:889:1: error: unable to find a register to spill in class 'GENERAL_REGS'
cvm.c:889:1: error: this is the insn:
(insn 11992 11991 11993 863 cvm_ptr.c:66 (set (mem:DI (plus:SI (plus:SI (mult:SI (reg:SI 6750 [ D.20325 ])
                        (const_int 8 [0x8]))
                    (reg/f:SI 6746 [ tempptr.3460 ]))
                (const_int 4 [0x4])) [16 S8 A64])
        (reg:DI 12123)) 88 {*movdi_2} (expr_list:REG_DEAD (reg:DI 12123)
        (expr_list:REG_DEAD (reg:SI 6750 [ D.20325 ])
            (expr_list:REG_DEAD (reg/f:SI 6746 [ tempptr.3460 ])
                (nil)))))
cvm.c:889:1: internal compiler error: in spill_failure, at reload1.c:2141
Please submit a full bug report,
with preprocessed source if appropriate.

Revision history for this message
In , Debian GCC maintainers (debian-gcc) wrote :

Created attachment 19411
preprocessed source

Revision history for this message
Matthias Klose (doko) wrote : Re: crash trying to build portable .net

adding -fomit-frame-pointer or just building with -O2 works around the problem

Changed in gcc-4.4 (Ubuntu):
importance: Undecided → Medium
status: New → Triaged
summary: - crash trying to build portable .net
+ [PR42536] crash trying to build portable .net
Changed in gcc:
status: Unknown → New
Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

With 3 register vars in the function (ebx, edi, esi) on the register starved ix86 the error is tollerable. From the 8 registers the programmer takes 3, %esp is fixed, without -fomit-frame-pointer %ebp is fixed too, which leaves just %eax, %edx and %ecx for register allocation. Even if this happens to compile, the result can't work fast, as almost all insns need to have temporaries spilled and reread back.

Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

Reduced testcase:
/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
/* { dg-options "-O2 -fno-gcse" } */

struct C;
struct B { struct C *b; };
struct C { void (*baz) (struct B *, void *, int); };
typedef union { int f; void *e; } D;
struct E { struct B *e; };
struct A { struct E *a1; D *a2; D *a3; };

void
foo (long *x, long y)
{
  *(long long *) x = y;
}

extern long fn1 (D);
extern void fn2 (void);

void
_bar (struct A *x)
{
  register int a asm ("esi");
  register D *volatile b asm ("edi");
  register int c asm ("ebx");
  void *d;
  asm volatile ("" : "=r" (a), "=r" (b), "=r" (c) : : "memory");
  if ((d = b[-2].e) != 0 && b [-2].e < d)
    {
      foo (&(((long *) d) + 1) [b[0].f], fn1 (b[-1]));
      x->a2 = (D *) c;
      x->a3 = b;
      fn2 ();
    }
  x->a1->e->b->baz (x->a1->e, (void *) (long) a, 1);
}

Wonder why RA doesn't try to force the memory address into register, that would free up one register from the 4 otherwise needed (2 for the address, 2 for DImode value being stored into the memory).

Changed in gcc:
status: New → Confirmed
Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

Jeff/Vlad, how hard would it be to try to split the insn into two insns instead of a spill failure (for insns using a MEM whose address uses more than one hard register) - one which forces the address into register (assuming it is supported) and the store (or load) which would use a simpler address form?

Revision history for this message
In , Law-redhat (law-redhat) wrote :

I guess it would be possible for reload to split an insn in some circumstances, particularly when there's complex addressing modes and multiple registers dying within the insn.

As you know, I've been poking at range splitting and we might be able to model this case too. Right now I split based on unallocated pseudos and expect to split ranges based on pseudos getting the wrong kind of register in the future.

However, there's a couple areas were we still want to split ranges and we may be able to come up with a generic way to express the other ranges we want to split:

Revision history for this message
In , Vmakarov (vmakarov) wrote :

(In reply to comment #4)
> Jeff/Vlad, how hard would it be to try to split the insn into two insns instead
> of a spill failure (for insns using a MEM whose address uses more than one hard
> register) - one which forces the address into register (assuming it is
> supported) and the store (or load) which would use a simpler address form?

If it is done in reload (and imho this is the most right place to do), I think it would be hard. It needs some person with a good knowledge of the reload.

It is also possible to do some splitting in other parts of compiler but it would an approximate solution (it means not all such cases will be avoided or/and it will hurt performance in general case).

Changed in gcc:
importance: Unknown → Medium
Revision history for this message
In , Pinskia (pinskia) wrote :

I cannot reproduce this bug on the trunk or 4.6.

Revision history for this message
In , Pinskia (pinskia) wrote :

(In reply to comment #7)
> I cannot reproduce this bug on the trunk or 4.6.

I want to say this is really a dup of bug 44174.

Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

4.4 branch is being closed, moving to 4.5.4 target.

Revision history for this message
In , Rguenth (rguenth) wrote :

The 4.5 branch is being closed, adjusting target milestone.

Revision history for this message
In , Ubizjak (ubizjak) wrote :

(In reply to comment #7)
> I cannot reproduce this bug on the trunk or 4.6.

Try with "-O2 -fno-gcse -fno-omit-frame-pointer -m32", it fails on 4.6+.

Reconfirmed.

Revision history for this message
In , Ubizjak (ubizjak) wrote :

(In reply to comment #11)

> Reconfirmed.

BTW: Moving the complex address to the temporary (as proposed in Comment #4) would help "atomic_compare_and_swap<dwi>_doubleword" on 32bit x86 targets, too. This pattern uses cmpxchg8b_pic_memory_operand predicate to limit the number of address registers for 32bit x86 targets, in order to avoid spill failures. Please see i386/sync.md.

Revision history for this message
In , stevenb (steven-gcc) wrote :

bug 55277 tracks the similar ICE in LRA instead of reload.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.