Issue Details (XML | Word | Printable)

Key: PCC-9
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Gregory McGarry
Reporter: Gregory McGarry
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
pcc

pcc/i386 compiled with itself doesn't work

Created: 03/Dec/08 08:17 AM   Updated: 15/Mar/09 11:16 AM
Component/s: C preprocessor
Affects Version/s: None
Fix Version/s: None

Environment:
pcc on ubuntu 8.04 (i386)
sources are from today


 Description  « Hide
pcc compiled with gcc works reasonably well.

ccom compiled with pcc has problems with the sizeof() operator. sizeof() always returns 0.

cpp compiled with pcc has problems with long comparisons eg (__STDC_VERSION__ > 199901L)

So, if logic is right: since cpp and ccom didn't crash unpredictably, it's unlikely that it is a codegen bug. So, maybe pcc is having a problem in the first pass. I'll continue to look for a specific fragment of C.

#include <stdio.h>

int
main()
{
printf("size = %d\n", sizeof(unsigned long int));
return 0;
}



 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Anders Magnusson added a comment - 03/Dec/08 05:26 PM
I tried to compile pcc with pcc on a BSD machine, and your testcase worked...? I have no Ubuntu available.

What does (__STDC_VERSION__ > 199901L) yield? It whould be false, isn't that true? It is so on my machine.

Gregory McGarry added a comment - 03/Dec/08 11:17 PM
/usr/include//features.h:185: error: Constant "199901L" is out of range


Gregory McGarry added a comment - 09/Feb/09 01:16 AM
The problem with large constants has been fixed on little-endian machines. The problem was with libpcc and the 64-bit emulation.

pcc cannot compile itself yet on Ubuntu.


Gregory McGarry added a comment - 19/Feb/09 10:55 PM
Jira #pcc-34 would also contribute to this problem.


Gregory McGarry added a comment - 19/Feb/09 10:57 PM
I have a fresh installation of NetBSD 5.0_RC2 and the latest revision of pcc from cvs, and I can confirm that repeated compilations of pcc with itself will eventually produce a build which will fail. On NetBSD, cpp dumps core.

On Ubuntu, it doesn't even get that far. It's interesting that the two systems fail in different ways. There may be two different bugs; the ubuntu problem is masking the second bug.


Gregory McGarry added a comment - 15/Mar/09 03:08 AM - edited
At least one problem exists in trees.c. By the fifth pass, pcc won't compile trees.c:

pass 1) gcc compiler - ok
pass 2) pcc compiler from pass 1 - ok
pass 3) pcc compiler from pass 2 - ok
pass 4) pcc compiler from pass 3 - ok
pass 5) pcc compiler from pass 4 - fail

In each case, the only file compiled with pcc is trees.c. all other files are always compiled with gcc. using netbsd/i386 5.0_RC2.

I compared the differences in the generated assembler between each pass. There are many differences between the gcc-generated assembler and the pcc-generated assembler, so it's not presented here.

The difference between pass2 and pass3 is:

--- stage2 2009-03-15 13:05:53.000000000 +1100
+++ stage3 2009-03-15 13:05:53.000000000 +1100
@@ -1,4 +1,4 @@
- .stabs "/tmp/ctm.04589a",100,0,0,.LL10
+ .stabs "/tmp/ctm.04098a",100,0,0,.LL10
 .LL10:
        .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
        .stabs "char:t2=r2;0;127;",128,0,0,0
@@ -1056,7 +1056,7 @@
        .stabs "c:5",128,0,8,26
        .align 4
 .L696:
- .long 0x0,0x0,0x8070000
+ .long 0x0,0x0,0x8080000
 .L700:
        .ascii "lvalue required\0"
        .stabs "sue2:29=*1",128,0,20,33
@@ -11881,8 +11881,8 @@
        pushl $15
        call tsize
        addl $12, %esp
- addl $7,%eax
- addl $0,%edx
+ subl $-7,%eax
+ sbbl $0,%edx
        pushl $0
        pushl $8
        pushl %edx


The difference between pass3 and pass4 is:

--- stage3 2009-03-15 13:05:53.000000000 +1100
+++ stage4 2009-03-15 13:05:53.000000000 +1100
@@ -1,4 +1,4 @@
- .stabs "/tmp/ctm.04098a",100,0,0,.LL10
+ .stabs "/tmp/ctm.04465a",100,0,0,.LL10
 .LL10:
  .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
  .stabs "char:t2=r2;0;127;",128,0,0,0
@@ -3286,7 +3286,7 @@
  movl %eax,%esi
  .stabn 68,0,536,.LL1031-findmember
 .LL1031:
- pushl $36
+ pushl $-536870875
  pushl %ebx
  leal (%esi),%eax
  pushl %eax
@@ -9408,7 +9408,7 @@
  .stabn 68,0,1757,.LL2219-comops
 .LL2219:
  movl %esi,%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%ebx),%eax
  pushl %eax
@@ -9882,7 +9882,7 @@
 .LL2315:
  movl 8(%ebp),%edx
  movl %edi,%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%edx),%eax
  pushl %eax
@@ -9942,7 +9942,7 @@
 .LL2327:
  movl 8(%ebp),%edx
  movl %edi,%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%edx),%eax
  pushl %eax
@@ -10732,7 +10732,7 @@
 .LL2494:
  movl 8(%ebp),%edx
  movl %esi,%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%edx),%eax
  pushl %eax
@@ -10826,7 +10826,7 @@
  .stabn 68,0,2046,.LL2523-rmcops
 .LL2523:
  movl 8(%ebp),%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%esi),%eax
  pushl %eax
@@ -10930,7 +10930,7 @@
 .LL2534:
  movl 8(%ebp),%edx
  movl %esi,%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%edx),%eax
  pushl %eax
@@ -12049,7 +12049,7 @@
  .stabn 68,0,2348,.LL2745-delvoid
 .LL2745:
  movl 8(%ebp),%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%edi),%eax
  pushl %eax
@@ -12083,7 +12083,7 @@
 .LL2750:
  movl 8(%ebp),%edx
  movl %esi,%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%edx),%eax
  pushl %eax
@@ -13201,7 +13201,7 @@
  .stabn 68,0,2562,.LL2950-ccopy
 .LL2950:
  movl %esi,%eax
- pushl $44
+ pushl $-536870867
  pushl %eax
  leal (%ebx),%eax
  pushl %eax

Gregory McGarry added a comment - 15/Mar/09 03:59 AM - edited
Consider the first difference in pass3: Label .L696 is used in buildtree() as:

        .stabn 68,0,235,.LL696-buildtree
.LL696:
        fldt .L696
        fldt 32(%esi)
        fxch
        fucompp
        fnstsw %ax
        andb $64,%ah
        je .L695

which corresponds to this code:

#define FLOAT_ISZERO(p) (p) == 0.0
 if (FLOAT_ISZERO(r->n_dcon))
         goto runtime;

The following code serves as a reference code fragment:

int test(long double f) { return f == 0.0; }

So it looks like the i386 back-end has a problem with long doubles.


The second difference looks weird: its trying to add 7 to a long long. The code generated in pass two isn't quite correct, since it isn't adding the carry. In this case to doesn't matter to the result. The code generated in pass3 is wrong. While the carry is considered, the top word of the long long wasn't negated. I cannot repoduce this case - maybe there is pressue on register usage which is causing the compiler to use MINUS instead of PLUS? - see #PCC-42.


Gregory McGarry added a comment - 15/Mar/09 04:24 AM - edited
Consider the second difference between pass2 and pass3:

The differences are always due to the wrong calculation of the structure sizes. So it looks like doszof() isn't quite doing the correct thing.

But interestingly, it's using the return value of tsize() in long long arithmetic. So this is probably the same problem as #PCC-42.

Gregory McGarry added a comment - 15/Mar/09 11:16 AM
fixed PLUS template