alpha: fix stack checking for alloca-ing a big chunk

Submitted by Tristan Gingold on Sept. 27, 2010, 8:58 a.m.


Message ID
State New
Headers show

Commit Message

Tristan Gingold Sept. 27, 2010, 8:58 a.m.

there is a flaw in the stack-probing loop of the computation of 'want' may wrap-around 0 and therefore
the loop will be skipped.  This may happen if the amount to allocate is larger than the current address of the stack pointer.
This condition happens several times in our Ada testsuite (on VMS, with images linked using /p0image).

This patch proposes one solution to fix this issue: instead of comparing the first probe address with the future value of SP,
it simply tests the amount of memory to be allocated.  This is bullet-proof but needs one more instruction.

An alternate solution would be to use GE instead of GEU as it is much less likely to wrap around 2**63 (given that no Alpha cpu
implemented 64 bits of VA - AFAIK).

We have such a patch for years and I sanity checked it on head.

OK for mainline ?


2010-09-27  Tristan Gingold  <>

	* config/alpha/ Change the initial condition of the
	probing loop.


Richard Henderson Sept. 27, 2010, 3:29 p.m.
On 09/27/2010 01:58 AM, Tristan Gingold wrote:
> 	* config/alpha/ Change the initial condition of the
> 	probing loop.



Patch hide | download patch | download mbox

--- a/gcc/config/alpha/
+++ b/gcc/config/alpha/
@@ -6588,15 +6588,17 @@ 
       emit_insn (gen_subdi3 (want, stack_pointer_rtx,
 			     force_reg (Pmode, operands[1])));
-      emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
       if (!CONST_INT_P (operands[1]))
+	  rtx limit = GEN_INT (4096);
 	  out_label = gen_label_rtx ();
-	  test = gen_rtx_GEU (VOIDmode, want, tmp);
-	  emit_jump_insn (gen_cbranchdi4 (test, want, tmp, out_label));
+	  test = gen_rtx_LTU (VOIDmode, operands[1], limit);
+	  emit_jump_insn
+	    (gen_cbranchdi4 (test, operands[1], limit, out_label));
+      emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
       emit_label (loop_label);
       memref = gen_rtx_MEM (DImode, tmp);
       MEM_VOLATILE_P (memref) = 1;