aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-08-09 23:08:33 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2017-08-09 23:08:33 +0200
commitcc6a467f450424a14bfc71d03e83b3981f4fc864 (patch)
tree8630b82450ca497021fe09a477cf138ac39daa8f /gcc
parenta8a581af9ec2c7c774b5309d9d4e6555ddfc440b (diff)
downloadgcc-cc6a467f450424a14bfc71d03e83b3981f4fc864.zip
gcc-cc6a467f450424a14bfc71d03e83b3981f4fc864.tar.gz
gcc-cc6a467f450424a14bfc71d03e83b3981f4fc864.tar.bz2
rs6000: Use SAVE_MULTIPLE only if we restore what it saves (PR80938)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000.c15
2 files changed, 21 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d3f9d2d..f69aeed 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 1fb9861..8f502db 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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.