rs6000: Use SAVE_MULTIPLE only if we restore what it saves (PR80938)
authorSegher Boessenkool <segher@kernel.crashing.org>
Wed, 9 Aug 2017 21:08:33 +0000 (23:08 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Wed, 9 Aug 2017 21:08:33 +0000 (23:08 +0200)
We can have SAVE_MULTIPLE while we do not have REST_MULTIPLE.  If the
inline restore does not restore all registers, the CFI for the save
and restore can conflict if things are shrink-wrapped.

We could restore all registers that are saved (not ideal), or emit
the CFI notes to say we did (which will work fine, but is also not
so great); instead, let's not save the registers that are unused.

PR target/80938
* config/rs6000/rs6000.c (rs6000_savres_strategy): Don't use
SAVE_MULTIPLE if not all the registers that saves, should be saved.

From-SVN: r251005

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index d3f9d2d515050d5bd3edd15c8ba28fae40435254..f69aeed99d3c7040b7d77fb9628f549f9e6f893b 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-09  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR target/80938
+       * config/rs6000/rs6000.c (rs6000_savres_strategy): Don't use
+       SAVE_MULTIPLE if not all the registers that saves, should be saved.
+
 2017-08-09  Jim Wilson  <jim.wilson@linaro.org>
 
        * config/aarch64/aarch64-cores.def (falkor): Use falkor pipeline.
index 1fb986181863962f0d9eaf812c1888c2cb334cea..8f502dbdf041efd99e833ab2f0d1a45339b47905 100644 (file)
@@ -24431,6 +24431,21 @@ rs6000_savres_strategy (rs6000_stack_t *info,
   else if (!lr_save_p && info->first_gp_reg_save > 29)
     strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
 
+  /* We can only use save multiple if we need to save all the registers from
+     first_gp_reg_save.  Otherwise, the CFI gets messed up (we save some
+     register we do not restore).  */
+  if (strategy & SAVE_MULTIPLE)
+    {
+      int i;
+
+      for (i = info->first_gp_reg_save; i < 32; i++)
+       if (fixed_reg_p (i) || !save_reg_p (i))
+         {
+           strategy &= ~SAVE_MULTIPLE;
+           break;
+         }
+    }
+
   /* We can only use load multiple or the out-of-line routines to
      restore gprs if we've saved all the registers from
      first_gp_reg_save.  Otherwise, we risk loading garbage.