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

login
register
mail settings
Submitter Tristan Gingold
Date Sept. 27, 2010, 8:58 a.m.
Message ID <C547FD16-A114-4175-9CF1-861659E06AEF@adacore.com>
Download mbox | patch
Permalink /patch/65821/
State New
Headers show

Comments

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

there is a flaw in the stack-probing loop of alpha.md:allocate_stack: 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 ?

Tristan.

2010-09-27  Tristan Gingold  <gingold@adacore.com>

	* config/alpha/alpha.md: 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/alpha.md: Change the initial condition of the
> 	probing loop.

Ok.


r~

Patch

--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -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;