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. Tested on powerpc64-linux {-m32,-m64}; committing to trunk. Segher 2017-08-09 Segher Boessenkool <seg...@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. --- gcc/config/rs6000/rs6000.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0f0b1ff..e8cdd25 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -24437,6 +24437,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. -- 1.9.3