[Bug libgomp/78468] [7 regression] libgomp.c/reduction-10.c and many more FAIL
vogt at linux dot vnet.ibm.com
gcc-bugzilla@gcc.gnu.org
Fri Nov 25 14:35:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78468
--- Comment #18 from Dominik Vogt <vogt at linux dot vnet.ibm.com> ---
Another approach may be to make the middleend ask the backend for the actual
value of REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM). Since on Sparc
the address is always 4 mod 8, we'd get an additional gap for *each* alloca()
if the size is still required to be a multiple of STACK_BOUNDARY.
To prevent this it would also be necessary to adapt the logic in
explow.c:get_dynamic_stack_size(). Since a recent patch this function also
uses REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) as the alignment of the
beginning of that block, but still rounds the size up to a multiple of
STACK_BOUNDARY (explow.c:round_push()):
-- get_dynamic_stack_size() --
/* Round the size to a multiple of the required stack alignment.
Since the stack is presumed to be rounded before this allocation,
this will maintain the required alignment.
If the stack grows downward, we could save an insn by subtracting
SIZE from the stack pointer and then aligning the stack pointer.
The problem with this is that the stack pointer may be unaligned
between the execution of the subtraction and alignment insns and
some machines do not allow this. Even on those that do, some
signal handlers malfunction if a signal should occur between those
insns. Since this is an extremely rare event, we have no reliable
way of knowing which systems have this problem. So we avoid even
momentarily mis-aligning the stack. */
if (size_align % MAX_SUPPORTED_STACK_ALIGNMENT != 0)
{
size = round_push (size);
-- END --
-- round_push() --
/* Round the size of a block to be pushed up to the boundary required
by this machine. SIZE is the desired size, which need not be constant. */
static rtx
round_push (rtx size)
{
rtx align_rtx, alignm1_rtx;
if (!SUPPORTS_STACK_ALIGNMENT
|| crtl->preferred_stack_boundary == MAX_SUPPORTED_STACK_ALIGNMENT)
{
int align = crtl->preferred_stack_boundary / BITS_PER_UNIT;
if (align == 1)
return size;
if (CONST_INT_P (size))
...
align_rtx = GEN_INT (align);
alignm1_rtx = GEN_INT (align - 1);
-- END --
It looks quite tricky to change this code to deal with preferred_stack_boundary
and REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) at the same time. What
if REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) is maller than
STACK_BOUNDARY and preferred_stack_boundary is larger than STACK_BOUNDARY?
In the end, both approaches result in the same amount of memory being
allocated.
More information about the Gcc-bugs
mailing list