gigatron-rom
gigatron-rom copied to clipboard
lcc: compiler crash
$ 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
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))))
Simplification of test program that crashes LCC:
char x;
int f(int c)
{
return x = c;
}
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.
This would be a good point to ask @pgavlin for some insights :-)
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.
I can work-around it in my C library and made a note in my updated Libs/stdio/fputc.c that found the issue.
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.
This issue should be closed since glcc fixes it.