If the user asks for a stack clash probe interval of 64kB, we currently generate a "stdu rX,-65536(r1)" instruction. That instruction does not exist (the offset is a 16-bit signed number). If the offset is too big we should force it into a register and generate a "stdux rX,rY,r1" instruction, instead.
Bootstrapped and regression checked on powerpc64-linux {-m32,-m64}; committing to trunk. Segher 2017-10-31 Segher Boessenkool <seg...@kernel.crsahing.org> PR target/82674 * config/rs6000/rs6000.md (allocate_stack): Force update interval into a register if it does not fit into an immediate offset field. --- gcc/config/rs6000/rs6000.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 62bd19b..18ebe8f 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10333,6 +10333,9 @@ (define_expand "allocate_stack" { rtx loop_lab, end_loop; bool rotated = CONST_INT_P (rounded_size); + rtx update = GEN_INT (-probe_interval); + if (probe_interval > 32768) + update = force_reg (Pmode, update); emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, last_addr, rotated); @@ -10340,13 +10343,11 @@ (define_expand "allocate_stack" if (Pmode == SImode) emit_insn (gen_movsi_update_stack (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-probe_interval), - chain)); + update, chain)); else emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-probe_interval), - chain)); + update, chain)); emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, last_addr, rotated); } -- 1.8.3.1