]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/69129 (ICE in get_attr_got, at config/mips/mips.md:694 on mips-linux...
authorNick Clifton <nickc@gcc.gnu.org>
Thu, 21 Jan 2016 14:07:01 +0000 (14:07 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Thu, 21 Jan 2016 14:07:01 +0000 (14:07 +0000)
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.

PR target/69129
* gcc.target/mips/pr69129.c: New.

From-SVN: r232674

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/pr69129.c [new file with mode: 0644]

index fd386b920505954e0bdc9d59161aa4b7659f88a7..e620e3064036707be7db3ec6b214e9a6cce32c9c 100644 (file)
@@ -1,3 +1,12 @@
+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
index ea18ad643e4046b7b25f54b936f6f2bc2d1dfa83..dd54d6ab37aff104181d52d8cdfac42387dfdd4e 100644 (file)
@@ -10347,8 +10347,6 @@ mips_compute_frame_info (void)
   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.
@@ -10375,6 +10373,26 @@ mips_compute_frame_info (void)
       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.  */
@@ -10520,12 +10538,6 @@ mips_compute_frame_info (void)
     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
index 25b72d7e0e6dd5786f0176d152745eff33320ed7..08aafd107222a46ddcd5fbcf539ee5d6435e50bb 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-21  Nick Clifton  <nickc@redhat.com>
+
+       PR target/69129
+       * gcc.target/mips/pr69129.c: New.
+
 2016-01-21  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58046
diff --git a/gcc/testsuite/gcc.target/mips/pr69129.c b/gcc/testsuite/gcc.target/mips/pr69129.c
new file mode 100644 (file)
index 0000000..186582f
--- /dev/null
@@ -0,0 +1,29 @@
+_Noreturn void fn1 (int) __attribute__((__visibility__("hidden")));
+
+void
+fn2 (void *p1)
+{
+  int a[7];
+  float *b;
+  int c, n;
+
+  if (c != p1) /* { dg-warning "comparison between pointer and integer" } */
+    fn1 (1);
+
+  n = 0;
+  for (; c; n++)
+    {
+      int d;
+      if (a[n] != d)
+       fn1(n);
+    }
+
+  b = p1;
+
+  while (1)
+    {
+      *b = 3.40282347e38f;
+      if (a[0])
+       return;
+    }
+}