aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2021-12-02 08:29:45 -0500
committerVladimir N. Makarov <vmakarov@redhat.com>2021-12-02 08:51:53 -0500
commitd47393d0b4d0d498795c4ae1353e6c156c1c4500 (patch)
tree2ed7bf96c76b5b350f3edce0296b6f3ee5f534fa
parent7d6c20c06ce4e5d595245af503b045c2032c02f7 (diff)
downloadgcc-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.c15
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)