PR 33755 is about a case in which 4.2 generates a %hi or local %got relocation without a partnering %lo relocation. This is wrong code, and leads to a linker error. The problem comes from dbr_schedule, although it's not really a bug there. We have: bne $5,$0,L1 # A ...stuff... L1: bne $5,$0,L2 # B ...printk call... L2: and nothing before dbr_schedule has managed to thread A to L2. dbr_schedule first fills B's delay slot with an lui from the printk block, then steal_delay_list_from_target realises that A can steal B's delay slot and branch directly to L2. There is no other path to L1, so the rest of the printk call is now dead. 4.3 doesn't manage to thread the jump due to differences further up the chain. Both 4.2 and 4.3 versions expand the switch statement to the following rtl: tmp = val & 1 if (tmp == 0) goto ... tmp2 = 1 if (tmp == tmp2) goto ... ...printk() code... 4.2 keeps the block in essentially this form up until combine, which uses nonzero_bits checks to optimise the second branch into "if (tmp != 0) goto ...". 4.3's loop-invariant motion can hoist the setting of tmp2, thus stopping combine from doing the optimisation. dbr_schedule isn't really where we'd want to optimise this case anyway. The dbr_schedule is there for other situations, where the threading is only possible when the delay slot is filled with an instruction from the target of the branch. We should ideally thread A to L2 much earlier, preferably at the tree level, and delete the whole printk block as dead. E.g. we probably ought to have some "nonzero bits" optimisations in tree VRP, if we don't already. (And if we don't already, I doubt I'll have been the first person to say that.) As far as 4.3 goes: if we need to keep the branch, what LIM is doing is perfectly reasonable; if we don't need to keep the branch, we should have optimised it away before LIM. For most targets, this is at worst a missed optimisation. I don't think the MIPS port can rely on the optimisation for correctness. So (alas!) I think the upshot is simply that we need to add some special code to mips_reorg to delete high-part relocations that have no matching lows. This sort of bug is something that has happened off and on since at least GCC 2 days, although the testcases tend to vary between releases, so this particular example is a 4.2 regression. Here are the patches I'm thinking of, one for mainline and 4.2. I've tested both on mips-linux-gnu. I'll hold off applying for a couple of days for comments. Richard