[patch] Fix PR middle-end/46894
Eric Botcazou
ebotcazou@adacore.com
Thu Jan 13 16:36:00 GMT 2011
Hi,
this is a fallout of Richard's stack realignment patch (PR rtl-opt/33721)
visible on PowerPC 32-bit. The problem is that in the checkg_32qi function:
typedef int __attribute__((mode(QI))) qi;
typedef qi __attribute__((vector_size (32))) v32qi;
typedef union U32QI { v32qi v; qi a[32]; } u32qi;
extern v32qi g_v32qi;
void checkg_32qi (void)
{
u32qi u;
qi *p = u.a;
u.v = g_v32qi;
checkp_32qi (p);
}
'u' overlaps 'p' on the stack:
(gdb) p &u
$26 = (u32qi *) 0xffffe500
(gdb) p &p
$27 = (qi **) 0xffffe518
The dynamic allocation for the super-aligned variable is broken:
(gdb) p/x $r1
$28 = 0xffffe510
(gdb) p/x $r0
$30 = 0xffffe500
the difference should be at least 32.
The wrong computation is done in allocate_dynamic_stack_space:
if (must_align)
{
unsigned extra, extra_align;
if (required_align > PREFERRED_STACK_BOUNDARY)
extra_align = PREFERRED_STACK_BOUNDARY;
else if (required_align > STACK_BOUNDARY)
extra_align = STACK_BOUNDARY;
else
extra_align = BITS_PER_UNIT;
extra = (required_align - extra_align) / BITS_PER_UNIT;
size = plus_constant (size, extra);
size = force_operand (size, NULL_RTX);
if (flag_stack_usage)
stack_usage_size += extra;
if (extra && size_align > extra_align)
size_align = extra_align;
}
(gdb) p required_align
$10 = 256
(gdb) p extra_align
$11 = 128
(gdb) p extra
$12 = 16
but virtual_stack_dynamic_rtx isn't aligned, i.e. STACK_DYNAMIC_OFFSET is
defined and isn't a multiple of PREFERRED_STACK_BOUNDARY, it's 8 here.
The attached patch forces extra_align to BITS_PER_UNIT in this case, i.e.
#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET)
must_align = true;
#endif
Now there is a hitch: since
2003-10-07 Geoffrey Keating <geoffk@apple.com>
* function.c (pad_to_arg_alignment): Take STACK_POINTER_OFFSET into
account when aligning arguments.
* calls.c (STACK_POINTER_OFFSET): Move default from here ...
* defaults.h (STACK_POINTER_OFFSET): ... to here.
STACK_POINTER_OFFSET is always defined, so we always align; with the patch,
we'll additionally always assume BITS_PER_UNIT. But I guess this latter
pessimization is dwarfed by the former. What do you think, Richard?
Lightly tested on x86 and PowerPC Linux for now.
2011-01-13 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/46894
* explow.c (allocate_dynamic_stack_space): Do not assume more than
BITS_PER_UNIT alignment if STACK_DYNAMIC_OFFSET or STACK_POINTER_OFFSET
are defined.
--
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr46894.diff
Type: text/x-diff
Size: 1591 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20110113/e2f2886e/attachment.bin>
More information about the Gcc-patches
mailing list