This fixes a bug discovered when we were evaluating the current state of -fstack-check. It ought to be able to go forward independent of the rest of the -fstack-check work.
The aarch64 specific code does not correctly handle large frames and will generate RTL with unrecognizable insns for such cases. This is clearly visible if -fstack-check is enabled by default or if it were to be added to the torture flags in the testsuite. I've tested this by bootstrapping and regression testing an aarch64 compiler with -fstack-check on by default and hacks to force all allocations/probing of more than PROBE_INTERVAL bytes to go through this path. It fixes a slew of testsuite failures (~80 for C and a few for Fortran and C++). One example is c-torture/compile/20031023-1.c which has a local frame of 0x10000000000 bytes. OK for the trunk? Jeff
* config/aarch64/aarch64.c (aarch64_emit_probe_stack_range): Handle frame sizes that do not satisfy aarch64_uimm12_shift. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 04417dc..4f89457 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2722,11 +2722,19 @@ aarch64_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size) plus_constant (Pmode, stack_pointer_rtx, -first)); /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */ - emit_set_insn (reg2, - plus_constant (Pmode, stack_pointer_rtx, - -(first + rounded_size))); - - + HOST_WIDE_INT adjustment = - (first + rounded_size); + if (! aarch64_uimm12_shift (adjustment)) + { + aarch64_internal_mov_immediate (reg2, GEN_INT (adjustment), + true, Pmode); + emit_set_insn (reg2, gen_rtx_PLUS (Pmode, stack_pointer_rtx, reg2)); + } + else + { + emit_set_insn (reg2, + plus_constant (Pmode, stack_pointer_rtx, adjustment)); + } + /* Step 3: the loop do