Better late than never... Ok, I think I nailed this, the simplest test case is: register unsigned long regval asm("g5"); extern void cond_resched(void); unsigned int var; void *expression(unsigned long regval) { void *ret; __asm__("" : "=r" (ret) : "0" (&var)); return ret + regval; } void func(void **pp) { int i; for (i = 0; i < 56; i++) { cond_resched(); *pp = expression(regval); } } If you build that with "gcc-4.2 -m64 -Os -S -o test.s test.c" the compiler moves expression() outside of the loop because it things it is invariant. The dataflow pass doesn't mark global registers correctly, and the new thing in gcc-4.2.x vs. gcc-4.1.x is that it uses the dataflow pass for the loop optimizers. I've bootstrapped and regression tested the following gcc-4.2.x patch, I'll test some test kernel builds after I get some sleep. --- ./gcc/df-scan.c.ORIG 2007-10-16 02:07:46.000000000 -0700 +++ ./gcc/df-scan.c 2007-10-16 23:00:32.000000000 -0700 @@ -1584,12 +1584,19 @@ df_insn_refs_record (struct dataflow *df so they are recorded as used. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (global_regs[i]) - df_uses_record (dflow, ®no_reg_rtx[i], - DF_REF_REG_USE, bb, insn, - 0); + { + df_uses_record (dflow, ®no_reg_rtx[i], + DF_REF_REG_USE, bb, insn, 0); + df_ref_record (dflow, regno_reg_rtx[i], ®no_reg_rtx[i], + bb, insn, DF_REF_REG_DEF, 0, true); + } + EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, ui, bi) - df_ref_record (dflow, regno_reg_rtx[ui], ®no_reg_rtx[ui], bb, - insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER, false); + { + if (!global_regs[ui]) + df_ref_record (dflow, regno_reg_rtx[ui], ®no_reg_rtx[ui], bb, + insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER, false); + } } } - To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html