diff options
author | Vladimir N. Makarov <vmakarov@redhat.com> | 2021-12-02 08:29:45 -0500 |
---|---|---|
committer | Vladimir N. Makarov <vmakarov@redhat.com> | 2021-12-02 08:51:53 -0500 |
commit | d47393d0b4d0d498795c4ae1353e6c156c1c4500 (patch) | |
tree | 2ed7bf96c76b5b350f3edce0296b6f3ee5f534fa | |
parent | 7d6c20c06ce4e5d595245af503b045c2032c02f7 (diff) | |
download | gcc-d47393d0b4d0d498795c4ae1353e6c156c1c4500.zip gcc-d47393d0b4d0d498795c4ae1353e6c156c1c4500.tar.gz gcc-d47393d0b4d0d498795c4ae1353e6c156c1c4500.tar.bz2 |
[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.
-rw-r--r-- | gcc/ira-color.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 3d01c60..1f80cbe 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) + || 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) |