use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
if (!hppa_save_pic_table_rtx)
- {
- hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
- emit_insn_before (gen_rtx (SET, VOIDmode,
- hppa_save_pic_table_rtx,
- pic_offset_table_rtx),
- call_insn);
- }
+ hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
+
+ /* We must save and restore the PIC register around every call
+ since we don't have flow information to determine if this save
+ is redundant with a previous save. The old code assumed once
+ the register was saved it never needs to be saved again, but
+ the save could have been on a path which doesn't always
+ execute; a call site physically later in the program would
+ then attempt a restore from an uninitialized register! */
+ emit_insn_before (gen_rtx (SET, VOIDmode,
+ hppa_save_pic_table_rtx,
+ pic_offset_table_rtx),
+ call_insn);
emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx,
hppa_save_pic_table_rtx));
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
if (!hppa_save_pic_table_rtx)
- {
- hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
- emit_insn_before (gen_rtx (SET, VOIDmode,
- hppa_save_pic_table_rtx,
- pic_offset_table_rtx),
- call_insn);
- }
+ hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
+
+ /* We must save and restore the PIC register around every call
+ since we don't have flow information to determine if this save
+ is redundant with a previous save. The old code assumed once
+ the register was saved it never needs to be saved again, but
+ the save could have been on a path which doesn't always
+ execute; a call site physically later in the program would
+ then attempt a restore from an uninitialized register! */
+ emit_insn_before (gen_rtx (SET, VOIDmode,
+ hppa_save_pic_table_rtx,
+ pic_offset_table_rtx),
+ call_insn);
emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx,
hppa_save_pic_table_rtx));