mirror of git://gcc.gnu.org/git/gcc.git
re PR middle-end/45234 (ICE in expand_call, at calls.c:2845 when passing aligned function argument from unaligned stack after alloca)
PR middle-end/45234 * rtl.h (enum global_rtl_index): Add GR_VIRTUAL_PREFERRED_STACK_BOUNDARY. (LAST_VIRTUAL_POINTER_REGISTER): Define. (virtual_preferred_stack_boundary_rtx, VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM): Define. (LAST_VIRTUAL_REGISTER): Increase by one. (REGNO_PTR_FRAME_P): Use LAST_VIRTUAL_POINTER_REGISTER instead of LAST_VIRTUAL_REGISTER. * function.c (instantiate_new_reg): Handle virtual_preferred_stack_boundary_rtx. * emit-rtl.c (init_virtual_regs): Handle VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM. (init_emit_regs): Initialize virtual_preferred_stack_boundary_rtx. * explow.c (round_push): If crtl->preferred_stack_boundary is smaller than MAX_SUPPORTED_STACK_ALIGNMENT, use virtual_preferred_stack_boundary_rtx alignment instead of crtl->preferred_stack_boundary alignment. (allocate_dynamic_stack_space): Use CONST_INT_P and REG_P macros. Never decrease crtl->preferred_stack_boundary, use crtl->preferred_stack_boundary or MAX_SUPPORTED_STACK_ALIGNMENT instead of PREFERRED_STACK_BOUNDARY. Don't modify stack_pointer_delta in dynamic allocation, even when size is constant. (probe_stack_range, anti_adjust_stack_and_probe): Use CONST_INT_P macro. * print-rtl.c (print_rtx): Handle VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM. * config/alpha/alpha.h (NONSTRICT_REG_OK_FP_BASE_P): Use LAST_VIRTUAL_POINTER_REGISTER instead of LAST_VIRTUAL_REGISTER. * config/frv/frv.c (frv_emit_movsi): Likewise. * config/arm/arm.c (thumb1_legitimate_address_p): Likewise. * config/rs6000/rs6000.c (virtual_stack_registers_memory_p): Likewise. * gcc.dg/torture/stackalign/alloca-6.c: New test. * gcc.target/i386/pr45234.c: New test. Revert: 2010-09-17 H.J. Lu <hongjiu.lu@intel.com> PR middle-end/45234 * calls.c (expand_call): Make sure that all variable sized adjustments are multiple of preferred stack boundary after stack alignment. From-SVN: r164593
This commit is contained in:
parent
3d1b7f135d
commit
32990d5bc2
|
|
@ -1,3 +1,48 @@
|
||||||
|
2010-09-24 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR middle-end/45234
|
||||||
|
* rtl.h (enum global_rtl_index): Add
|
||||||
|
GR_VIRTUAL_PREFERRED_STACK_BOUNDARY.
|
||||||
|
(LAST_VIRTUAL_POINTER_REGISTER): Define.
|
||||||
|
(virtual_preferred_stack_boundary_rtx,
|
||||||
|
VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM): Define.
|
||||||
|
(LAST_VIRTUAL_REGISTER): Increase by one.
|
||||||
|
(REGNO_PTR_FRAME_P): Use LAST_VIRTUAL_POINTER_REGISTER
|
||||||
|
instead of LAST_VIRTUAL_REGISTER.
|
||||||
|
* function.c (instantiate_new_reg): Handle
|
||||||
|
virtual_preferred_stack_boundary_rtx.
|
||||||
|
* emit-rtl.c (init_virtual_regs): Handle
|
||||||
|
VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM.
|
||||||
|
(init_emit_regs): Initialize virtual_preferred_stack_boundary_rtx.
|
||||||
|
* explow.c (round_push): If crtl->preferred_stack_boundary
|
||||||
|
is smaller than MAX_SUPPORTED_STACK_ALIGNMENT, use
|
||||||
|
virtual_preferred_stack_boundary_rtx alignment instead of
|
||||||
|
crtl->preferred_stack_boundary alignment.
|
||||||
|
(allocate_dynamic_stack_space): Use CONST_INT_P and REG_P
|
||||||
|
macros. Never decrease crtl->preferred_stack_boundary,
|
||||||
|
use crtl->preferred_stack_boundary or MAX_SUPPORTED_STACK_ALIGNMENT
|
||||||
|
instead of PREFERRED_STACK_BOUNDARY. Don't modify
|
||||||
|
stack_pointer_delta in dynamic allocation, even when size
|
||||||
|
is constant.
|
||||||
|
(probe_stack_range, anti_adjust_stack_and_probe): Use CONST_INT_P
|
||||||
|
macro.
|
||||||
|
* print-rtl.c (print_rtx): Handle
|
||||||
|
VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM.
|
||||||
|
* config/alpha/alpha.h (NONSTRICT_REG_OK_FP_BASE_P): Use
|
||||||
|
LAST_VIRTUAL_POINTER_REGISTER instead of LAST_VIRTUAL_REGISTER.
|
||||||
|
* config/frv/frv.c (frv_emit_movsi): Likewise.
|
||||||
|
* config/arm/arm.c (thumb1_legitimate_address_p): Likewise.
|
||||||
|
* config/rs6000/rs6000.c (virtual_stack_registers_memory_p):
|
||||||
|
Likewise.
|
||||||
|
|
||||||
|
Revert:
|
||||||
|
2010-09-17 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR middle-end/45234
|
||||||
|
* calls.c (expand_call): Make sure that all variable sized
|
||||||
|
adjustments are multiple of preferred stack boundary after
|
||||||
|
stack alignment.
|
||||||
|
|
||||||
2010-09-24 Iain Sandoe <iains@gcc.gnu.org>
|
2010-09-24 Iain Sandoe <iains@gcc.gnu.org>
|
||||||
Dominique Dhumieres <dominiq@lps.ens.fr>
|
Dominique Dhumieres <dominiq@lps.ens.fr>
|
||||||
|
|
||||||
|
|
|
||||||
13
gcc/calls.c
13
gcc/calls.c
|
|
@ -2385,19 +2385,6 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
|
|
||||||
preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;
|
preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;
|
||||||
|
|
||||||
if (SUPPORTS_STACK_ALIGNMENT)
|
|
||||||
{
|
|
||||||
/* All variable sized adjustments must be multiple of preferred
|
|
||||||
stack boundary. Stack alignment may change preferred stack
|
|
||||||
boundary after variable sized adjustments have been made. We
|
|
||||||
need to compensate it here. */
|
|
||||||
unsigned HOST_WIDE_INT delta
|
|
||||||
= ((stack_pointer_delta - pending_stack_adjust)
|
|
||||||
% preferred_unit_stack_boundary);
|
|
||||||
if (delta)
|
|
||||||
anti_adjust_stack (GEN_INT (preferred_unit_stack_boundary - delta));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We want to make two insn chains; one for a sibling call, the other
|
/* We want to make two insn chains; one for a sibling call, the other
|
||||||
for a normal call. We will select one of the two chains after
|
for a normal call. We will select one of the two chains after
|
||||||
initial RTL generation is complete. */
|
initial RTL generation is complete. */
|
||||||
|
|
|
||||||
|
|
@ -916,7 +916,7 @@ extern int alpha_memory_latency;
|
||||||
#define NONSTRICT_REG_OK_FP_BASE_P(X) \
|
#define NONSTRICT_REG_OK_FP_BASE_P(X) \
|
||||||
(REGNO (X) == 31 || REGNO (X) == 63 \
|
(REGNO (X) == 31 || REGNO (X) == 63 \
|
||||||
|| (REGNO (X) >= FIRST_PSEUDO_REGISTER \
|
|| (REGNO (X) >= FIRST_PSEUDO_REGISTER \
|
||||||
&& REGNO (X) < LAST_VIRTUAL_REGISTER))
|
&& REGNO (X) < LAST_VIRTUAL_POINTER_REGISTER))
|
||||||
|
|
||||||
/* Nonzero if X is a hard reg that can be used as a base reg. */
|
/* Nonzero if X is a hard reg that can be used as a base reg. */
|
||||||
#define STRICT_REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
|
#define STRICT_REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
|
||||||
|
|
|
||||||
|
|
@ -5855,7 +5855,8 @@ thumb1_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
|
||||||
&& (REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
|
&& (REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
|
||||||
|| REGNO (XEXP (x, 0)) == ARG_POINTER_REGNUM
|
|| REGNO (XEXP (x, 0)) == ARG_POINTER_REGNUM
|
||||||
|| (REGNO (XEXP (x, 0)) >= FIRST_VIRTUAL_REGISTER
|
|| (REGNO (XEXP (x, 0)) >= FIRST_VIRTUAL_REGISTER
|
||||||
&& REGNO (XEXP (x, 0)) <= LAST_VIRTUAL_REGISTER))
|
&& REGNO (XEXP (x, 0))
|
||||||
|
<= LAST_VIRTUAL_POINTER_REGISTER))
|
||||||
&& GET_MODE_SIZE (mode) >= 4
|
&& GET_MODE_SIZE (mode) >= 4
|
||||||
&& GET_CODE (XEXP (x, 1)) == CONST_INT
|
&& GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||||
&& (INTVAL (XEXP (x, 1)) & 3) == 0)
|
&& (INTVAL (XEXP (x, 1)) & 3) == 0)
|
||||||
|
|
|
||||||
|
|
@ -4067,7 +4067,7 @@ frv_emit_movsi (rtx dest, rtx src)
|
||||||
|| (GET_CODE (src) == REG
|
|| (GET_CODE (src) == REG
|
||||||
&& IN_RANGE_P (REGNO (src),
|
&& IN_RANGE_P (REGNO (src),
|
||||||
FIRST_VIRTUAL_REGISTER,
|
FIRST_VIRTUAL_REGISTER,
|
||||||
LAST_VIRTUAL_REGISTER))))
|
LAST_VIRTUAL_POINTER_REGISTER))))
|
||||||
{
|
{
|
||||||
emit_insn (gen_rtx_SET (VOIDmode, dest, copy_to_mode_reg (SImode, src)));
|
emit_insn (gen_rtx_SET (VOIDmode, dest, copy_to_mode_reg (SImode, src)));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
||||||
|
|
@ -5489,7 +5489,7 @@ virtual_stack_registers_memory_p (rtx op)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (regnum >= FIRST_VIRTUAL_REGISTER
|
return (regnum >= FIRST_VIRTUAL_REGISTER
|
||||||
&& regnum <= LAST_VIRTUAL_REGISTER);
|
&& regnum <= LAST_VIRTUAL_POINTER_REGISTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
||||||
|
|
@ -5376,6 +5376,8 @@ init_virtual_regs (void)
|
||||||
regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
|
regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
|
||||||
regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
|
regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
|
||||||
regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
|
regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
|
||||||
|
regno_reg_rtx[VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM]
|
||||||
|
= virtual_preferred_stack_boundary_rtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -5698,6 +5700,8 @@ init_emit_regs (void)
|
||||||
virtual_outgoing_args_rtx =
|
virtual_outgoing_args_rtx =
|
||||||
gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
|
gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
|
||||||
virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
|
virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
|
||||||
|
virtual_preferred_stack_boundary_rtx =
|
||||||
|
gen_raw_REG (Pmode, VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM);
|
||||||
|
|
||||||
/* Initialize RTL for commonly used hard registers. These are
|
/* Initialize RTL for commonly used hard registers. These are
|
||||||
copied into regno_reg_rtx as we begin to compile each function. */
|
copied into regno_reg_rtx as we begin to compile each function. */
|
||||||
|
|
|
||||||
77
gcc/explow.c
77
gcc/explow.c
|
|
@ -915,30 +915,47 @@ anti_adjust_stack (rtx adjust)
|
||||||
static rtx
|
static rtx
|
||||||
round_push (rtx size)
|
round_push (rtx size)
|
||||||
{
|
{
|
||||||
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
|
rtx align_rtx, alignm1_rtx;
|
||||||
|
|
||||||
if (align == 1)
|
if (!SUPPORTS_STACK_ALIGNMENT
|
||||||
return size;
|
|| crtl->preferred_stack_boundary == MAX_SUPPORTED_STACK_ALIGNMENT)
|
||||||
|
|
||||||
if (CONST_INT_P (size))
|
|
||||||
{
|
{
|
||||||
HOST_WIDE_INT new_size = (INTVAL (size) + align - 1) / align * align;
|
int align = crtl->preferred_stack_boundary / BITS_PER_UNIT;
|
||||||
|
|
||||||
if (INTVAL (size) != new_size)
|
if (align == 1)
|
||||||
size = GEN_INT (new_size);
|
return size;
|
||||||
|
|
||||||
|
if (CONST_INT_P (size))
|
||||||
|
{
|
||||||
|
HOST_WIDE_INT new_size = (INTVAL (size) + align - 1) / align * align;
|
||||||
|
|
||||||
|
if (INTVAL (size) != new_size)
|
||||||
|
size = GEN_INT (new_size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
align_rtx = GEN_INT (align);
|
||||||
|
alignm1_rtx = GEN_INT (align - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* CEIL_DIV_EXPR needs to worry about the addition overflowing,
|
/* If crtl->preferred_stack_boundary might still grow, use
|
||||||
but we know it can't. So add ourselves and then do
|
virtual_preferred_stack_boundary_rtx instead. This will be
|
||||||
TRUNC_DIV_EXPR. */
|
substituted by the right value in vregs pass and optimized
|
||||||
size = expand_binop (Pmode, add_optab, size, GEN_INT (align - 1),
|
during combine. */
|
||||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
align_rtx = virtual_preferred_stack_boundary_rtx;
|
||||||
size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, GEN_INT (align),
|
alignm1_rtx = force_operand (plus_constant (align_rtx, -1), NULL_RTX);
|
||||||
NULL_RTX, 1);
|
|
||||||
size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CEIL_DIV_EXPR needs to worry about the addition overflowing,
|
||||||
|
but we know it can't. So add ourselves and then do
|
||||||
|
TRUNC_DIV_EXPR. */
|
||||||
|
size = expand_binop (Pmode, add_optab, size, alignm1_rtx,
|
||||||
|
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||||
|
size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, align_rtx,
|
||||||
|
NULL_RTX, 1);
|
||||||
|
size = expand_mult (Pmode, size, align_rtx, NULL_RTX, 1);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1144,9 +1161,9 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align,
|
||||||
introduced later by the various alignment operations. */
|
introduced later by the various alignment operations. */
|
||||||
if (flag_stack_usage)
|
if (flag_stack_usage)
|
||||||
{
|
{
|
||||||
if (GET_CODE (size) == CONST_INT)
|
if (CONST_INT_P (size))
|
||||||
stack_usage_size = INTVAL (size);
|
stack_usage_size = INTVAL (size);
|
||||||
else if (GET_CODE (size) == REG)
|
else if (REG_P (size))
|
||||||
{
|
{
|
||||||
/* Look into the last emitted insn and see if we can deduce
|
/* Look into the last emitted insn and see if we can deduce
|
||||||
something for the register. */
|
something for the register. */
|
||||||
|
|
@ -1154,10 +1171,10 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align,
|
||||||
insn = get_last_insn ();
|
insn = get_last_insn ();
|
||||||
if ((set = single_set (insn)) && rtx_equal_p (SET_DEST (set), size))
|
if ((set = single_set (insn)) && rtx_equal_p (SET_DEST (set), size))
|
||||||
{
|
{
|
||||||
if (GET_CODE (SET_SRC (set)) == CONST_INT)
|
if (CONST_INT_P (SET_SRC (set)))
|
||||||
stack_usage_size = INTVAL (SET_SRC (set));
|
stack_usage_size = INTVAL (SET_SRC (set));
|
||||||
else if ((note = find_reg_equal_equiv_note (insn))
|
else if ((note = find_reg_equal_equiv_note (insn))
|
||||||
&& GET_CODE (XEXP (note, 0)) == CONST_INT)
|
&& CONST_INT_P (XEXP (note, 0)))
|
||||||
stack_usage_size = INTVAL (XEXP (note, 0));
|
stack_usage_size = INTVAL (XEXP (note, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1177,7 +1194,8 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align,
|
||||||
/* We can't attempt to minimize alignment necessary, because we don't
|
/* We can't attempt to minimize alignment necessary, because we don't
|
||||||
know the final value of preferred_stack_boundary yet while executing
|
know the final value of preferred_stack_boundary yet while executing
|
||||||
this code. */
|
this code. */
|
||||||
crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
|
if (crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
|
||||||
|
crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
|
||||||
|
|
||||||
/* We will need to ensure that the address we return is aligned to
|
/* We will need to ensure that the address we return is aligned to
|
||||||
BIGGEST_ALIGNMENT. If STACK_DYNAMIC_OFFSET is defined, we don't
|
BIGGEST_ALIGNMENT. If STACK_DYNAMIC_OFFSET is defined, we don't
|
||||||
|
|
@ -1195,7 +1213,7 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align,
|
||||||
#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET)
|
#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET)
|
||||||
#define MUST_ALIGN 1
|
#define MUST_ALIGN 1
|
||||||
#else
|
#else
|
||||||
#define MUST_ALIGN (PREFERRED_STACK_BOUNDARY < BIGGEST_ALIGNMENT)
|
#define MUST_ALIGN (crtl->preferred_stack_boundary < BIGGEST_ALIGNMENT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (MUST_ALIGN)
|
if (MUST_ALIGN)
|
||||||
|
|
@ -1255,13 +1273,13 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align,
|
||||||
insns. Since this is an extremely rare event, we have no reliable
|
insns. Since this is an extremely rare event, we have no reliable
|
||||||
way of knowing which systems have this problem. So we avoid even
|
way of knowing which systems have this problem. So we avoid even
|
||||||
momentarily mis-aligning the stack. */
|
momentarily mis-aligning the stack. */
|
||||||
if (!known_align_valid || known_align % PREFERRED_STACK_BOUNDARY != 0)
|
if (!known_align_valid || known_align % MAX_SUPPORTED_STACK_ALIGNMENT != 0)
|
||||||
{
|
{
|
||||||
size = round_push (size);
|
size = round_push (size);
|
||||||
|
|
||||||
if (flag_stack_usage)
|
if (flag_stack_usage)
|
||||||
{
|
{
|
||||||
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
|
int align = crtl->preferred_stack_boundary / BITS_PER_UNIT;
|
||||||
stack_usage_size = (stack_usage_size + align - 1) / align * align;
|
stack_usage_size = (stack_usage_size + align - 1) / align * align;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1328,6 +1346,8 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align,
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
int saved_stack_pointer_delta;
|
||||||
|
|
||||||
#ifndef STACK_GROWS_DOWNWARD
|
#ifndef STACK_GROWS_DOWNWARD
|
||||||
emit_move_insn (target, virtual_stack_dynamic_rtx);
|
emit_move_insn (target, virtual_stack_dynamic_rtx);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1358,10 +1378,15 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align,
|
||||||
emit_label (space_available);
|
emit_label (space_available);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saved_stack_pointer_delta = stack_pointer_delta;
|
||||||
if (flag_stack_check && STACK_CHECK_MOVING_SP)
|
if (flag_stack_check && STACK_CHECK_MOVING_SP)
|
||||||
anti_adjust_stack_and_probe (size, false);
|
anti_adjust_stack_and_probe (size, false);
|
||||||
else
|
else
|
||||||
anti_adjust_stack (size);
|
anti_adjust_stack (size);
|
||||||
|
/* Even if size is constant, don't modify stack_pointer_delta.
|
||||||
|
The constant size alloca should preserve
|
||||||
|
crtl->preferred_stack_boundary alignment. */
|
||||||
|
stack_pointer_delta = saved_stack_pointer_delta;
|
||||||
|
|
||||||
#ifdef STACK_GROWS_DOWNWARD
|
#ifdef STACK_GROWS_DOWNWARD
|
||||||
emit_move_insn (target, virtual_stack_dynamic_rtx);
|
emit_move_insn (target, virtual_stack_dynamic_rtx);
|
||||||
|
|
@ -1572,7 +1597,7 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
|
||||||
{
|
{
|
||||||
rtx addr;
|
rtx addr;
|
||||||
|
|
||||||
if (GET_CODE (temp) == CONST_INT)
|
if (CONST_INT_P (temp))
|
||||||
{
|
{
|
||||||
/* Use [base + disp} addressing mode if supported. */
|
/* Use [base + disp} addressing mode if supported. */
|
||||||
HOST_WIDE_INT offset = INTVAL (temp);
|
HOST_WIDE_INT offset = INTVAL (temp);
|
||||||
|
|
@ -1613,7 +1638,7 @@ anti_adjust_stack_and_probe (rtx size, bool adjust_back)
|
||||||
|
|
||||||
/* If we have a constant small number of probes to generate, that's the
|
/* If we have a constant small number of probes to generate, that's the
|
||||||
easy case. */
|
easy case. */
|
||||||
if (GET_CODE (size) == CONST_INT && INTVAL (size) < 7 * PROBE_INTERVAL)
|
if (CONST_INT_P (size) && INTVAL (size) < 7 * PROBE_INTERVAL)
|
||||||
{
|
{
|
||||||
HOST_WIDE_INT isize = INTVAL (size), i;
|
HOST_WIDE_INT isize = INTVAL (size), i;
|
||||||
bool first_probe = true;
|
bool first_probe = true;
|
||||||
|
|
|
||||||
|
|
@ -1405,6 +1405,11 @@ instantiate_new_reg (rtx x, HOST_WIDE_INT *poffset)
|
||||||
#endif
|
#endif
|
||||||
offset = cfa_offset;
|
offset = cfa_offset;
|
||||||
}
|
}
|
||||||
|
else if (x == virtual_preferred_stack_boundary_rtx)
|
||||||
|
{
|
||||||
|
new_rtx = GEN_INT (crtl->preferred_stack_boundary / BITS_PER_UNIT);
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NULL_RTX;
|
return NULL_RTX;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -457,6 +457,9 @@ print_rtx (const_rtx in_rtx)
|
||||||
fprintf (outfile, " %d virtual-outgoing-args", value);
|
fprintf (outfile, " %d virtual-outgoing-args", value);
|
||||||
else if (value == VIRTUAL_CFA_REGNUM)
|
else if (value == VIRTUAL_CFA_REGNUM)
|
||||||
fprintf (outfile, " %d virtual-cfa", value);
|
fprintf (outfile, " %d virtual-cfa", value);
|
||||||
|
else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
|
||||||
|
fprintf (outfile, " %d virtual-preferred-stack-boundary",
|
||||||
|
value);
|
||||||
else
|
else
|
||||||
fprintf (outfile, " %d virtual-reg-%d", value,
|
fprintf (outfile, " %d virtual-reg-%d", value,
|
||||||
value-FIRST_VIRTUAL_REGISTER);
|
value-FIRST_VIRTUAL_REGISTER);
|
||||||
|
|
|
||||||
16
gcc/rtl.h
16
gcc/rtl.h
|
|
@ -2010,6 +2010,7 @@ enum global_rtl_index
|
||||||
GR_VIRTUAL_STACK_DYNAMIC,
|
GR_VIRTUAL_STACK_DYNAMIC,
|
||||||
GR_VIRTUAL_OUTGOING_ARGS,
|
GR_VIRTUAL_OUTGOING_ARGS,
|
||||||
GR_VIRTUAL_CFA,
|
GR_VIRTUAL_CFA,
|
||||||
|
GR_VIRTUAL_PREFERRED_STACK_BOUNDARY,
|
||||||
|
|
||||||
GR_MAX
|
GR_MAX
|
||||||
};
|
};
|
||||||
|
|
@ -2157,7 +2158,18 @@ extern rtx gen_rtx_MEM (enum machine_mode, rtx);
|
||||||
|
|
||||||
#define VIRTUAL_CFA_REGNUM ((FIRST_VIRTUAL_REGISTER) + 4)
|
#define VIRTUAL_CFA_REGNUM ((FIRST_VIRTUAL_REGISTER) + 4)
|
||||||
|
|
||||||
#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4)
|
#define LAST_VIRTUAL_POINTER_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4)
|
||||||
|
|
||||||
|
/* This is replaced by crtl->preferred_stack_boundary / BITS_PER_UNIT
|
||||||
|
when finalized. */
|
||||||
|
|
||||||
|
#define virtual_preferred_stack_boundary_rtx \
|
||||||
|
(global_rtl[GR_VIRTUAL_PREFERRED_STACK_BOUNDARY])
|
||||||
|
|
||||||
|
#define VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM \
|
||||||
|
((FIRST_VIRTUAL_REGISTER) + 5)
|
||||||
|
|
||||||
|
#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 5)
|
||||||
|
|
||||||
/* Nonzero if REGNUM is a pointer into the stack frame. */
|
/* Nonzero if REGNUM is a pointer into the stack frame. */
|
||||||
#define REGNO_PTR_FRAME_P(REGNUM) \
|
#define REGNO_PTR_FRAME_P(REGNUM) \
|
||||||
|
|
@ -2166,7 +2178,7 @@ extern rtx gen_rtx_MEM (enum machine_mode, rtx);
|
||||||
|| (REGNUM) == HARD_FRAME_POINTER_REGNUM \
|
|| (REGNUM) == HARD_FRAME_POINTER_REGNUM \
|
||||||
|| (REGNUM) == ARG_POINTER_REGNUM \
|
|| (REGNUM) == ARG_POINTER_REGNUM \
|
||||||
|| ((REGNUM) >= FIRST_VIRTUAL_REGISTER \
|
|| ((REGNUM) >= FIRST_VIRTUAL_REGISTER \
|
||||||
&& (REGNUM) <= LAST_VIRTUAL_REGISTER))
|
&& (REGNUM) <= LAST_VIRTUAL_POINTER_REGISTER))
|
||||||
|
|
||||||
/* REGNUM never really appearing in the INSN stream. */
|
/* REGNUM never really appearing in the INSN stream. */
|
||||||
#define INVALID_REGNUM (~(unsigned int) 0)
|
#define INVALID_REGNUM (~(unsigned int) 0)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2010-09-24 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR middle-end/45234
|
||||||
|
* gcc.dg/torture/stackalign/alloca-6.c: New test.
|
||||||
|
* gcc.target/i386/pr45234.c: New test.
|
||||||
|
|
||||||
2010-09-24 Richard Guenther <rguenther@suse.de>
|
2010-09-24 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
* gcc.dg/lto/20091006-2_0.c: Prune warnings.
|
* gcc.dg/lto/20091006-2_0.c: Prune warnings.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* PR middle-end/45234 */
|
||||||
|
/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
|
||||||
|
/* { dg-options "-mincoming-stack-boundary=2 -mpreferred-stack-boundary=2" } */
|
||||||
|
|
||||||
|
#include "check.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
__attribute__ ((noinline))
|
||||||
|
bar (__float128 f)
|
||||||
|
{
|
||||||
|
check (&f, __alignof__(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile int z = 6;
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
char *p = __builtin_alloca (z);
|
||||||
|
|
||||||
|
bar (0);
|
||||||
|
|
||||||
|
__builtin_strncpy (p, "good", 5);
|
||||||
|
if (__builtin_strncmp (p, "good", 5) != 0)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
p[z - 1] = '\0';
|
||||||
|
printf ("Failed: %s != good\n", p);
|
||||||
|
#endif
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* PR middle-end/45234 */
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-march=i586" { target ilp32 } } */
|
||||||
|
|
||||||
|
struct S { union { double b[4]; } a[18]; } s, a[5];
|
||||||
|
void foo (struct S);
|
||||||
|
struct S bar (struct S, struct S *, struct S);
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (struct S arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
baz (void)
|
||||||
|
{
|
||||||
|
foo (bar (s, &a[1], a[2]));
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue