gigatron-rom icon indicating copy to clipboard operation
gigatron-rom copied to clipboard

lcc: compiler crash

Open kervinck opened this issue 5 years ago • 8 comments

$ cat test2.c
struct S {
  char c;                       // 'int c' works...
};
int f(int c, struct S *s)
{
  return s->c = c;              // just 's->c = c' without return works...
}
$ make test2.gt1
Utils/lcc/build/lcc -ILibs -c test2.c -o test2.o
Utils/lcc/build/lcc: fatal error in Utils/lcc/build/rcc
make: *** [test2.o] Error 1
$

Edit: see simplification below

kervinck avatar May 11 '19 12:05 kervinck

Crash happens in emitasm, before returning:

emitasm(0x7fc2a3012338, ASGNU1, (none)) (action)

In

        act = IR->x._actions[rulenum];
[...]
                act(p);

(Note: rulenum == 26)

Jumping to:

static void inst_strunc(Node p)
[...]
        unsigned to = p->kids[0]->syms[0]->x.regnode->number;

Was introduced with https://github.com/kervinck/gigatron-rom/commit/5916cb261b0b7aa866af4d381e29aca736bdd206

p->kids[0]->syms[0]->x.regnode is a null pointer.

(Note: p->kids[0]->syms[RX].x.regnode is a null pointer as well)

dumptree(p) after entering inst_strunc() gives:

ASGNU1(VREGP(1), CVUU1(INDIRI2(ADDRFP2(c))))

kervinck avatar May 13 '19 12:05 kervinck

Simplification of test program that crashes LCC:

char x;
int f(int c)
{
  return x = c;
}

kervinck avatar May 13 '19 17:05 kervinck

Interestingly, this was commented out in https://github.com/kervinck/gigatron-rom/commit/e58bf0c1c3e4b975875aedfb65f0398835d8d59e

Utils/lcc/src/gen.c:

//	case CVI: case CVU: case CVP:
//		if (optype(p->op) != F
//		&&  opsize(p->op) <= p->syms[0]->u.c.v.i)
//			p->op = LOAD + opkind(p->op);
//		break;

If we re-enable, the compilation completes without crashing LCC itself. Resulting output:

asm.defun('_f')
asm.push()
asm.ldwi(0xc0)
asm.call('enter')
asm.ldi(6)
asm.call('ldloc')
asm.stw('r7')
asm.ldwi('_x')
asm.stw('r6')
asm.ldw('r7')
asm.poke('r6')
asm.ldw('r7')
asm.stw('rv')
asm.label('.L1')
asm.ldwi(0x600)
asm.call('leave')
asm.ldi(2)
asm.addw('sp')
asm.stw('sp')
asm.ldw('rv')
asm.pop()
asm.ret()
asm.defun('_x')
asm.dx([0] * 1)

This looks correct to me and gttest passes. However......... Libs/Example.c doesn't work anymore. There are many changes in the emitted code (mostly ANDI $ff instructions are now gone) and, for example, __lookup/LUP is broken:

Before:
0cd3  21 48                    LDW   $48                |!H|
0cd5  7f 00                    LUP   $00                |..|
0cd7  82 ff                    ANDI  $ff                |..|
0cd9  f0 3c                    POKE  $3c                |.<|
0cdb  b4 cb                    SYS   134                |..|

After:
0cc2  21 48                    LDW   $48                |!H|
0cc4  7f 00                    LUP   $00                |..|
0cc6  21 3a                    LDW   $3a                |!:| <-- ???
0cc8  f0 3c                    POKE  $3c                |.<|
0cca  b4 cb                    SYS   134                |..|

Close, but no cigar.

kervinck avatar May 13 '19 17:05 kervinck

This would be a good point to ask @pgavlin for some insights :-)

kervinck avatar May 13 '19 18:05 kervinck

This is the point at which I wish that I had gone back and commented things up a bit more.

I disabled the conversion of CVI/CVU/CVP to LOAD because it was breaking the backend's assumption that all LOADs are from vAC to a virtual register or vice-versa. We could probably tweak things such that the conversion works, but I'm not 100% certain what those tweaks would be offhand.

It's a bit strange that the register allocator appears not to be allocating those nodes... I'll try running cpp and rcc manually (rather than via the driver) to get debug output.

pgavlin avatar May 13 '19 20:05 pgavlin

I can work-around it in my C library and made a note in my updated Libs/stdio/fputc.c that found the issue.

kervinck avatar May 13 '19 20:05 kervinck

Fyi, I spent the best part of the last few days on the other issue: https://github.com/kervinck/gigatron-rom/issues/76 https://github.com/kervinck/gigatron-rom/issues/76

Basically: nested multiplicative expressions such as "a * (b / c)" don’t compile.

LCC gets in an infinite loop of spilling and reloading vAC but I’m stuck at understanding it. It spills vAC at some point, which is fine and understandable. Later it reloads, but at that point vAC is allocated, so it wants to spill it again. etc

(The message “inserting load from vAC to vAC” looks like a red herring.)

On 13 May 2019, at 22:24, Pat Gavlin [email protected] wrote:

This is the point at which I wish that I had gone back and commented things up a bit more.

I disabled the conversion of CVI/CVU/CVP to LOAD because it was breaking the backend's assumption that all LOADs are from vAC to a virtual register or vice-versa. We could probably tweak things such that the conversion works, but I'm not 100% certain what those tweaks would be offhand.

It's a bit strange that the register allocator appears not to be allocating those nodes... I'll try running cpp and rcc manually (rather than via the driver) to get debug output.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kervinck/gigatron-rom/issues/73?email_source=notifications&email_token=AC5ZS3RQX5PESYR3DRMWR7DPVHFBDA5CNFSM4HMH77S2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVJOQVI#issuecomment-491972693, or mute the thread https://github.com/notifications/unsubscribe-auth/AC5ZS3TAAZL7C6DWWHYZEUDPVHFBDANCNFSM4HMH77SQ.

kervinck avatar May 19 '19 04:05 kervinck

This issue should be closed since glcc fixes it.

lb3361 avatar Aug 25 '22 12:08 lb3361