public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* The macro STACK_BOUNDARY may overflow
@ 2023-03-24 13:48 Paul Iannetta
  2023-03-25 16:28 ` Jeff Law
  0 siblings, 1 reply; 3+ messages in thread
From: Paul Iannetta @ 2023-03-24 13:48 UTC (permalink / raw)
  To: gcc

Hi,

Currently, the macro STACK_BOUNDARY is defined as

  Macro: STACK_BOUNDARY
     Define this macro to the minimum alignment enforced by hardware for
     the stack pointer on this machine.  The definition is a C
     expression for the desired alignment (measured in bits).  This
     value is used as a default if 'PREFERRED_STACK_BOUNDARY' is not
     defined.  On most machines, this should be the same as
     'PARM_BOUNDARY'.

with no mentions about its type and bounds.  However, at some point, the value
of this macro gets assigned to the field "regno_pointer_align" of "struct
emit_status" which points to an "unsigned char", hence if STACK_BOUNDARY gets
bigger than 255, it will overflow...  Thankfully, the backend which defines the
highest value is microblaze with 128 < 255.

The assignment happens in "emit-rtl.c" through the REGNO_POINTER_ALIGN macro:

in function.h:
  #define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
in emit-rtl.cc:
  REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
  [...]
  REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;

Would it be possible to, either add an explicit bound to STACK_BOUNDARY in the
manual, and/or use an "unsigned int *" rather than and "unsigned char *" for
the field "regno_pointer_align".

Thanks,
Paul





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: The macro STACK_BOUNDARY may overflow
  2023-03-24 13:48 The macro STACK_BOUNDARY may overflow Paul Iannetta
@ 2023-03-25 16:28 ` Jeff Law
  2024-01-12 10:15   ` Paul Iannetta
  0 siblings, 1 reply; 3+ messages in thread
From: Jeff Law @ 2023-03-25 16:28 UTC (permalink / raw)
  To: gcc



On 3/24/23 07:48, Paul Iannetta via Gcc wrote:
> Hi,
> 
> Currently, the macro STACK_BOUNDARY is defined as
> 
>    Macro: STACK_BOUNDARY
>       Define this macro to the minimum alignment enforced by hardware for
>       the stack pointer on this machine.  The definition is a C
>       expression for the desired alignment (measured in bits).  This
>       value is used as a default if 'PREFERRED_STACK_BOUNDARY' is not
>       defined.  On most machines, this should be the same as
>       'PARM_BOUNDARY'.
> 
> with no mentions about its type and bounds.  However, at some point, the value
> of this macro gets assigned to the field "regno_pointer_align" of "struct
> emit_status" which points to an "unsigned char", hence if STACK_BOUNDARY gets
> bigger than 255, it will overflow...  Thankfully, the backend which defines the
> highest value is microblaze with 128 < 255.
> 
> The assignment happens in "emit-rtl.c" through the REGNO_POINTER_ALIGN macro:
> 
> in function.h:
>    #define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
> in emit-rtl.cc:
>    REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
>    [...]
>    REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
> 
> Would it be possible to, either add an explicit bound to STACK_BOUNDARY in the
> manual, and/or use an "unsigned int *" rather than and "unsigned char *" for
> the field "regno_pointer_align".
Feel free to send a suitable patch to gcc-patches.  THe alignment data 
isn't held in the RTX structures, so it's not critical that it be kept 
as small as possible.  We don't want to waste space, so an unsigned 
short might be better.  A char was good for 30 years, so we don't need 
to go crazy here.

The alternative would be to change the representation to store the log2 
of the alignment.  That would be a much larger change and would trade 
off runtime for memory consumption.  I would have suggested this 
approach if the data were in the RTX structures amd space at a premium.

While I do see a trend in processor design to reduce/remove the 
misalignment penalties (thus eliminating the driver for increasing data 
alignment), that's been primarily in high end designs.

jeff


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: The macro STACK_BOUNDARY may overflow
  2023-03-25 16:28 ` Jeff Law
@ 2024-01-12 10:15   ` Paul Iannetta
  0 siblings, 0 replies; 3+ messages in thread
From: Paul Iannetta @ 2024-01-12 10:15 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc

On Sat, Mar 25, 2023 at 10:28:02AM -0600, Jeff Law via Gcc wrote:
> On 3/24/23 07:48, Paul Iannetta via Gcc wrote:
> > Hi,
> > 
> > Currently, the macro STACK_BOUNDARY is defined as
> > 
> >    Macro: STACK_BOUNDARY
> >       Define this macro to the minimum alignment enforced by hardware for
> >       the stack pointer on this machine.  The definition is a C
> >       expression for the desired alignment (measured in bits).  This
> >       value is used as a default if 'PREFERRED_STACK_BOUNDARY' is not
> >       defined.  On most machines, this should be the same as
> >       'PARM_BOUNDARY'.
> > 
> > with no mentions about its type and bounds.  However, at some point, the value
> > of this macro gets assigned to the field "regno_pointer_align" of "struct
> > emit_status" which points to an "unsigned char", hence if STACK_BOUNDARY gets
> > bigger than 255, it will overflow...  Thankfully, the backend which defines the
> > highest value is microblaze with 128 < 255.
> > 
> > The assignment happens in "emit-rtl.c" through the REGNO_POINTER_ALIGN macro:
> > 
> > in function.h:
> >    #define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
> > in emit-rtl.cc:
> >    REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
> >    [...]
> >    REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
> > 
> > Would it be possible to, either add an explicit bound to STACK_BOUNDARY in the
> > manual, and/or use an "unsigned int *" rather than and "unsigned char *" for
> > the field "regno_pointer_align".
> Feel free to send a suitable patch to gcc-patches.  THe alignment data isn't
> held in the RTX structures, so it's not critical that it be kept as small as
> possible.  We don't want to waste space, so an unsigned short might be
> better.  A char was good for 30 years, so we don't need to go crazy here.
> 
> The alternative would be to change the representation to store the log2 of
> the alignment.  That would be a much larger change and would trade off
> runtime for memory consumption.  I would have suggested this approach if the
> data were in the RTX structures amd space at a premium.
> 
> While I do see a trend in processor design to reduce/remove the misalignment
> penalties (thus eliminating the driver for increasing data alignment),
> that's been primarily in high end designs.
> 
> jeff

Hi,

Here is a patch that changes the type of the variable holding the
alignment to unsigned short for the reasons outlined above.  Should I
also mention the new upper bound for STACK_BOUNDARY in the
documentation or keep it silent?

Thanks,
Paul

---->8-------------------------------------------------------8<----
From: Paul Iannetta <piannetta@kalrayinc.com>
Date: Fri, 12 Jan 2024 10:18:34 +0100
Subject: [PATCH] make regno_pointer_align a unsigned short*

This changes allows to align values greater than 128 to be used for
alignment.

	* emit-rtl.cc (emit_status::ensure_regno_capacity): Change
	  unsigned char* to unsigned short*
	(init_emit): Likewise.
	* function.h (struct GTY): Likewise.
---
 gcc/emit-rtl.cc | 6 +++---
 gcc/function.h  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index 1856fa4884f..f0f0ad193b5 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -1231,9 +1231,9 @@ emit_status::ensure_regno_capacity ()
   while (reg_rtx_no >= new_size)
     new_size *= 2;
 
-  char *tmp = XRESIZEVEC (char, regno_pointer_align, new_size);
+  short *tmp = XRESIZEVEC (short, regno_pointer_align, new_size);
   memset (tmp + old_size, 0, new_size - old_size);
-  regno_pointer_align = (unsigned char *) tmp;
+  regno_pointer_align = (unsigned short *) tmp;
 
   rtx *new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, new_size);
   memset (new1 + old_size, 0, (new_size - old_size) * sizeof (rtx));
@@ -5972,7 +5972,7 @@ init_emit (void)
   crtl->emit.regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
 
   crtl->emit.regno_pointer_align
-    = XCNEWVEC (unsigned char, crtl->emit.regno_pointer_align_length);
+    = XCNEWVEC (unsigned short, crtl->emit.regno_pointer_align_length);
 
   regno_reg_rtx
     = ggc_cleared_vec_alloc<rtx> (crtl->emit.regno_pointer_align_length);
diff --git a/gcc/function.h b/gcc/function.h
index 2d775b877fc..c4a20060844 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -72,7 +72,7 @@ struct GTY(()) emit_status {
   /* Indexed by pseudo register number, if nonzero gives the known alignment
      for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
      Allocated in parallel with x_regno_reg_rtx.  */
-  unsigned char * GTY((skip)) regno_pointer_align;
+  unsigned short * GTY((skip)) regno_pointer_align;
 };






^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-01-12 10:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-24 13:48 The macro STACK_BOUNDARY may overflow Paul Iannetta
2023-03-25 16:28 ` Jeff Law
2024-01-12 10:15   ` Paul Iannetta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).