On Thu, Dec 02, 2021 at 08:53:31AM -0500, Vladimir Makarov via Gcc-patches wrote: > The following patch fixes > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103437 > > The patch was successfully bootstrapped and tested on x86-64. There is no > test as the bug occurs on GCC built with sanitizing for an existing go test.
> commit c6cf5ac1522c54b2ced98fc687e973a9ff17ba1e > Author: Vladimir N. Makarov <vmaka...@redhat.com> > Date: Thu Dec 2 08:29:45 2021 -0500 > > [PR103437] Process multiplication overflow in priority calculation for > allocno assignments > > We process overflows in cost calculations but for huge functions > priority calculation can overflow as priority can be bigger the cost > used for it. The patch fixes the problem. > > gcc/ChangeLog: > > PR rtl-optimization/103437 > * ira-color.c (setup_allocno_priorities): Process multiplication > overflow. > > diff --git a/gcc/ira-color.c b/gcc/ira-color.c > index 3d01c60800c..1f80cbea0e2 100644 > --- a/gcc/ira-color.c > +++ b/gcc/ira-color.c > @@ -2796,7 +2796,7 @@ static int *allocno_priorities; > static void > setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n) > { > - int i, length, nrefs, priority, max_priority, mult; > + int i, length, nrefs, priority, max_priority, mult, diff; > ira_allocno_t a; > > max_priority = 0; > @@ -2807,11 +2807,14 @@ setup_allocno_priorities (ira_allocno_t > *consideration_allocnos, int n) > ira_assert (nrefs >= 0); > mult = floor_log2 (ALLOCNO_NREFS (a)) + 1; > ira_assert (mult >= 0); > - allocno_priorities[ALLOCNO_NUM (a)] > - = priority > - = (mult > - * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)) > - * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); > + mult *= ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]; > + diff = ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a); > + /* Multiplication can overflow for very large functions. > + Check the overflow and constrain the result if necessary: */ > + if (__builtin_smul_overflow (mult, diff, &priority) I'm afraid we can't use __builtin_smul_overflow, not all system compilers will have that. But, as it is done in int and we kind of rely on int being 32-bit on host and rely on long long being 64-bit, I think you can do something like: long long priorityll = (long long) mult * diff; priority = priorityll; if (priorityll != priority ... > + || priority <= -INT_MAX) > + priority = diff >= 0 ? INT_MAX : -INT_MAX; > + allocno_priorities[ALLOCNO_NUM (a)] = priority; > if (priority < 0) > priority = -priority; > if (max_priority < priority) Jakub