+2016-01-21 Bernd Enlinger <bernd.edlinger@hotmail.de>
+ Nick Clifton <nickc@redhat.com>
+
+ PR target/69129
+ PR target/69012
+ * config/mips/mips.c (mips_compute_frame_info): Initialise
+ args_size and hard_frame_pointer_offset fields of the frame
+ structure before calling mips_global_pointer.
+
2016-01-21 David Edelsohn <dje.gcc@gmail.com>
* configure.ac (gcc_cv_as_dwloc): Test support for debug frame section
memset (frame, 0, sizeof (*frame));
size = get_frame_size ();
- cfun->machine->global_pointer = mips_global_pointer ();
-
/* The first two blocks contain the outgoing argument area and the $gp save
slot. This area isn't needed in leaf functions. We can also skip it
if we know that none of the called functions will use this space.
frame->args_size = crtl->outgoing_args_size;
frame->cprestore_size = MIPS_GP_SAVE_AREA_SIZE;
}
+
+ /* MIPS16 code offsets the frame pointer by the size of the outgoing
+ arguments. This tends to increase the chances of using unextended
+ instructions for local variables and incoming arguments. */
+ if (TARGET_MIPS16)
+ frame->hard_frame_pointer_offset = frame->args_size;
+
+ /* PR 69129 / 69012: Beware of a possible race condition. mips_global_pointer
+ might call mips_cfun_has_inflexible_gp_ref_p which in turn can call
+ mips_find_gp_ref which will iterate over the current insn sequence.
+ If any of these insns use the cprestore_save_slot_operand or
+ cprestore_load_slot_operand predicates in order to be recognised then
+ they will call mips_cprestore_address_p which calls
+ mips_get_cprestore_base_and_offset which expects the frame information
+ to be filled in... In fact mips_get_cprestore_base_and_offset only
+ needs the args_size and hard_frame_pointer_offset fields to be filled
+ in, which is why the global_pointer field is initialised here and not
+ earlier. */
+ cfun->machine->global_pointer = mips_global_pointer ();
+
offset = frame->args_size + frame->cprestore_size;
/* Move above the local variables. */
frame->acc_save_offset = frame->acc_sp_offset - offset;
if (frame->num_cop0_regs > 0)
frame->cop0_save_offset = frame->cop0_sp_offset - offset;
-
- /* MIPS16 code offsets the frame pointer by the size of the outgoing
- arguments. This tends to increase the chances of using unextended
- instructions for local variables and incoming arguments. */
- if (TARGET_MIPS16)
- frame->hard_frame_pointer_offset = frame->args_size;
}
/* Return the style of GP load sequence that is being used for the