------- Comment #35 from jakub at gcc dot gnu dot org 2007-12-11 21:28 ------- df_get_entry_block_def_set has this: /* Once the prologue has been generated, all of these registers should just show up in the first regular block. */ if (HAVE_prologue && epilogue_completed) { /* Defs for the callee saved registers are inserted so that the pushes have some defining location. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if ((call_used_regs[i] == 0) && (df_regs_ever_live_p (i))) bitmap_set_bit (entry_block_defs, i); } else { ... r = targetm.calls.struct_value_rtx (current_function_decl, true); if (r && REG_P (r)) bitmap_set_bit (entry_block_defs, REGNO (r)); }
So, apparently struct_value_rtx is already considered, but only before prologues/epilogues are inserted (or the arch doesn't HAVE_prologue). On PA call_used_regs[28] != 0, so the comment "Once the prologue ..." doesn't make sense for it, because the if part won't ever set %r28 in entry_block_defs, even when it is needed. I've tried: --- df-scan.c.jj 2007-10-26 13:45:44.000000000 +0200 +++ df-scan.c 2007-12-11 22:24:21.000000000 +0100 @@ -3530,12 +3530,12 @@ df_get_entry_block_def_set (bitmap entry bitmap_set_bit (entry_block_defs, STATIC_CHAIN_REGNUM); #endif #endif - - r = targetm.calls.struct_value_rtx (current_function_decl, true); - if (r && REG_P (r)) - bitmap_set_bit (entry_block_defs, REGNO (r)); } + r = targetm.calls.struct_value_rtx (current_function_decl, true); + if (r && REG_P (r)) + bitmap_set_bit (entry_block_defs, REGNO (r)); + if ((!reload_completed) || frame_pointer_needed) { /* Any reference to any pseudo before reload is a potential patch and it indeed probably cures this testcase. The diff in assembly is: ... comib,>= 0,%r24,L$0025 stw %r4,-72(%r30) comib,= 1,%r24,L$0026 - ldil LR'L$C0002,%r28 + ldil LR'L$C0003,%r19 stw %r7,-52(%r30) ldw 4(%r26),%r20 ldo -112(%r30),%r25 ldo -120(%r30),%r26 stw %r20,-116(%r30) ldw 4(%r6),%r19 ldw 0(%r3),%r20 stw %r19,-108(%r30) stw %r20,-120(%r30) ldw 0(%r6),%r19 .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR bl _Z4foo1I1DIiEPFbiiEET_S4_S4_iRKiT0_,%r2 stw %r19,-112(%r30) ... L$0026: - ldil LR'L$C0003,%r19 + ldil LR'L$C0002,%r28 ldw 4(%r26),%r20 ldo RR'L$C0002(%r28),%r9 ldil LR'L$C0001,%r28 ... which looks promissing (though of course without access to PA I can't be sure it works). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32636