Skip to content

Commit

Permalink
Merge pull request #3622 from WalterBright/fix12855
Browse files Browse the repository at this point in the history
fix Issue 12855 - Shadow register assignments for spilling can conflict
  • Loading branch information
MartinNowak authored and WalterBright committed Jun 9, 2014
1 parent 5fd5212 commit c0d0452
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
28 changes: 24 additions & 4 deletions src/backend/cgreg.c
Expand Up @@ -271,9 +271,10 @@ int cgreg_benefit(Symbol *s,int reg, Symbol *retsym)
benefit = 0;
retsym_cnt = 0;

#if 0 // causes assert failure in std.range(4488) from std.parallelism's unit tests
#if 1 // causes assert failure in std.range(4488) from std.parallelism's unit tests
// (it works now - but keep an eye on it for the moment)
// If s is passed in a register to the function, favor that register
if (s->Sclass == SCfastpar && s->Spreg == reg)
if ((s->Sclass == SCfastpar || s->Sclass == SCshadowreg) && s->Spreg == reg)
++benefit;
#endif

Expand Down Expand Up @@ -397,10 +398,10 @@ int cgreg_benefit(Symbol *s,int reg, Symbol *retsym)

#ifdef DEBUG
//printf("2weights: dfotop = %d, globsym.top = %d\n", dfotop, globsym.top);
if (benefit > s->Sweight + retsym_cnt)
if (benefit > s->Sweight + retsym_cnt + 1)
printf("s = '%s', benefit = %d, Sweight = %d, retsym_cnt = x%x\n",s->Sident,benefit,s->Sweight, retsym_cnt);
#endif
assert(benefit <= s->Sweight + retsym_cnt);
assert(benefit <= s->Sweight + retsym_cnt + 1);
return benefit;

Lcant:
Expand Down Expand Up @@ -820,6 +821,15 @@ int cgreg_assign(Symbol *retsym)
regm_t dst_integer_mask = mask[dst_integer_reg];
regm_t dst_float_mask = mask[dst_float_reg];

/* Find all the parameters passed as registers
*/
regm_t regparams = 0;
for (size_t si = 0; si < globsym.top; si++)
{ symbol *s = globsym.tab[si];
if (s->Sclass == SCfastpar || s->Sclass == SCshadowreg)
regparams |= s->Spregm();
}

// Find symbol t, which is the most 'deserving' symbol that should be
// placed into a register.
Reg t;
Expand Down Expand Up @@ -883,6 +893,12 @@ int cgreg_assign(Symbol *retsym)
if (reg == BX && !(allregs & mBX))
continue;
#endif
/* Don't assign register parameter to another register parameter
*/
if ((s->Sclass == SCfastpar || s->Sclass == SCshadowreg) &&
mask[reg] & regparams &&
reg != s->Spreg)
continue;

if (s->Sflags & GTbyte &&
!(mask[reg] & BYTEREGS))
Expand Down Expand Up @@ -912,6 +928,10 @@ int cgreg_assign(Symbol *retsym)
goto Ltried; // tried and failed to assign MSW
if (regmsw == reg) // can't assign msw and lsw to same reg
continue;
if ((s->Sclass == SCfastpar || s->Sclass == SCshadowreg) &&
mask[regmsw] & regparams &&
regmsw != s->Spreg2)
continue;
#ifdef DEBUG
if (debugr)
{ printf(".%s",regstring[regmsw]);
Expand Down
14 changes: 12 additions & 2 deletions src/backend/cod3.c
Expand Up @@ -3939,12 +3939,22 @@ code* gen_spill_reg(Symbol* s, bool toreg)
cs.orReg(s->Sreglsw);
if (I64 && sz == 1 && s->Sreglsw >= 4)
cs.Irex |= REX;
c = gen(c,&cs);
if ((cs.Irm & 0xC0) == 0xC0 && // reg,reg
(((cs.Irm >> 3) ^ cs.Irm) & 7) == 0 && // registers match
(((cs.Irex >> 2) ^ cs.Irex) & 1) == 0) // REX_R and REX_B match
; // skip MOV reg,reg
else
c = gen(c,&cs);
if (sz > REGSIZE)
{
cs.setReg(s->Sregmsw);
getlvalue_msw(&cs);
c = gen(c,&cs);
if ((cs.Irm & 0xC0) == 0xC0 && // reg,reg
(((cs.Irm >> 3) ^ cs.Irm) & 7) == 0 && // registers match
(((cs.Irex >> 2) ^ cs.Irex) & 1) == 0) // REX_R and REX_B match
; // skip MOV reg,reg
else
c = gen(c,&cs);
}
}

Expand Down

0 comments on commit c0d0452

Please sign in to comment.