Here's some code to reproduce a register allocation bug
where a temporary value overwrites a variable, leading
to wrong results. I have only been able to reproduce
the problem with large memory model.
The variable "next_block" is allocated to R2/R3 and is
used inside a for loop. The loop's execution
overwrites R2/R3 each time the loop is re-run, which
causes the program to assign a wrong value if the
"next_block" variable is used after the first iteration
of the loop.
You can also download a copy of the code here:
http://www.pjrc.com/tmp/test.c
#ifndef SDCC_MODEL_LARGE
#error "This bug only shows up in large memory model"
#endif
struct simple_list_struct {
unsigned int next;
};
static data unsigned int first_block=0;
static xdata at 0x7000 struct simple_list_struct p7;
void test(unsigned int val)
{
unsigned int block, next_block;
next_block = p7.next + 1234; /* assigned to
r2/r3 */
for (block = first_block; block != 0; block =
p7.next) {
if (p7.next == val) {
p7.next = next_block;
return;
}
/* BUG: "block = p7.next" overwrites
r2/r3 */
}
}
Logged In: YES
user_id=1551
Fixed please update SDCCloop.c (fix). SDCCcflow.c (removed
temp fix)
Logged In: YES
user_id=63512
This wasn't a good fix. Infact it creates even bigger problems
e.g. in gets.c where str[r567] and count[r01] weren't saved
over the putchar() call after the return in the '\r' case where
their liverange ended. Getchar() doesn't use these registers
so it was never noticed, but still ...
Undid in SDCCloop.c:1.32
A better fix is on it's way.
Logged In: YES
user_id=635249
I have verified that the new live range code (specifically,
Klaus's 2003/10/28 cvs commit) has fixed this bug.