haifa-sched: Avoid overflows in extend_h_i_d [PR112411]

Message ID ZXLHoMaZQbNKF3vh@tucnak
State Unresolved
Headers
Series haifa-sched: Avoid overflows in extend_h_i_d [PR112411] |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Jakub Jelinek Dec. 8, 2023, 7:37 a.m. UTC
  On Thu, Dec 07, 2023 at 11:54:01AM +0100, Jakub Jelinek wrote:
> On Thu, Dec 07, 2023 at 09:36:23AM +0100, Jakub Jelinek wrote:
> > Without the dg-skip-if I got on 64-bit host:
> > cc1: out of memory allocating 571230784744 bytes after a total of 2772992 bytes
> 
> I've looked at this and the problem is in haifa-sched.cc:
> 9047	      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2, true);
> get_max_uid () is 0x4000024d with the --param min-nondebug-insn-uid=0x40000000
> and so 3 * get_max_uid () / 2 actually overflows to -536870028 but as vec.h
> then treats the value as unsigned, it attempts to allocate
> 0xe0000374U * 152UL bytes, i.e. those 532GB.  If the above is fixed to do
> 3U * get_max_uid () / 2 instead, it will get slightly better and will only
> need 0x60000373U * 152UL bytes, i.e. 228GB.

Here it is in a patch form.
For the other changes, it would be more work and the question is if it would
be beneficial for average compilation, if the uids aren't sparse enough,
it would waste more memory (8-bytes per uid for the pointer in the array
plus the 152 byte allocation, probably even rounded up for next bucket size
unless we use say pool allocator).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2023-12-08  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/112411
	* haifa-sched.cc (extend_h_i_d): Use 3U instead of 3 in
	3 * get_max_uid () / 2 calculation.


	Jakub
  

Comments

Richard Biener Dec. 8, 2023, 7:39 a.m. UTC | #1
On Fri, 8 Dec 2023, Jakub Jelinek wrote:

> On Thu, Dec 07, 2023 at 11:54:01AM +0100, Jakub Jelinek wrote:
> > On Thu, Dec 07, 2023 at 09:36:23AM +0100, Jakub Jelinek wrote:
> > > Without the dg-skip-if I got on 64-bit host:
> > > cc1: out of memory allocating 571230784744 bytes after a total of 2772992 bytes
> > 
> > I've looked at this and the problem is in haifa-sched.cc:
> > 9047	      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2, true);
> > get_max_uid () is 0x4000024d with the --param min-nondebug-insn-uid=0x40000000
> > and so 3 * get_max_uid () / 2 actually overflows to -536870028 but as vec.h
> > then treats the value as unsigned, it attempts to allocate
> > 0xe0000374U * 152UL bytes, i.e. those 532GB.  If the above is fixed to do
> > 3U * get_max_uid () / 2 instead, it will get slightly better and will only
> > need 0x60000373U * 152UL bytes, i.e. 228GB.
> 
> Here it is in a patch form.
> For the other changes, it would be more work and the question is if it would
> be beneficial for average compilation, if the uids aren't sparse enough,
> it would waste more memory (8-bytes per uid for the pointer in the array
> plus the 152 byte allocation, probably even rounded up for next bucket size
> unless we use say pool allocator).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2023-12-08  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/112411
> 	* haifa-sched.cc (extend_h_i_d): Use 3U instead of 3 in
> 	3 * get_max_uid () / 2 calculation.
> 
> --- gcc/haifa-sched.cc.jj	2023-08-08 15:55:06.705161670 +0200
> +++ gcc/haifa-sched.cc	2023-12-07 11:57:17.869611646 +0100
> @@ -9044,7 +9044,7 @@ extend_h_i_d (void)
>    if (reserve > 0
>        && ! h_i_d.space (reserve))
>      {
> -      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2, true);
> +      h_i_d.safe_grow_cleared (3U * get_max_uid () / 2, true);
>        sched_extend_target ();
>      }
>  }
> 
> 	Jakub
> 
>
  

Patch

--- gcc/haifa-sched.cc.jj	2023-08-08 15:55:06.705161670 +0200
+++ gcc/haifa-sched.cc	2023-12-07 11:57:17.869611646 +0100
@@ -9044,7 +9044,7 @@  extend_h_i_d (void)
   if (reserve > 0
       && ! h_i_d.space (reserve))
     {
-      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2, true);
+      h_i_d.safe_grow_cleared (3U * get_max_uid () / 2, true);
       sched_extend_target ();
     }
 }