diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 7c2be01c120..62bd4e2072f 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -3426,13 +3426,19 @@ 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)); @@ -3522,13 +3528,19 @@ 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));