From: Vladimir Makarov Date: Wed, 5 Apr 2017 15:07:51 +0000 (+0000) Subject: re PR rtl-optimization/70703 (Regression in register usage on x86) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e2323a2b77c91d1ba8194b01e6deaa2e00f15990;p=gcc.git re PR rtl-optimization/70703 (Regression in register usage on x86) 2017-04-05 Vladimir Makarov PR rtl-optimization/70703 * ira-color.c (update_costs_from_allocno): Use the smallest mode. (update_conflict_hard_regno_costs): Use long instead of unsigned arithmetic for cost calculation. 2017-04-05 Vladimir Makarov PR rtl-optimization/70703 * gcc.target/i386/pr70703.c: New. From-SVN: r246707 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0158a389ad7..951e0401ed1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-04-05 Vladimir Makarov + + PR rtl-optimization/70703 + * ira-color.c (update_costs_from_allocno): Use the smallest mode. + (update_conflict_hard_regno_costs): Use long instead of unsigned + arithmetic for cost calculation. + 2017-04-05 Jakub Jelinek Bernd Edlinger diff --git a/gcc/ira-color.c b/gcc/ira-color.c index ab981730eba..7886db4ffff 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -1367,6 +1367,16 @@ update_costs_from_allocno (ira_allocno_t allocno, int hard_regno, || ALLOCNO_ASSIGNED_P (another_allocno)) continue; + if (GET_MODE_SIZE (ALLOCNO_MODE (cp->second)) < GET_MODE_SIZE (mode)) + /* If we have different modes use the smallest one. It is + a sub-register move. It is hard to predict what LRA + will reload (the pseudo or its sub-register) but LRA + will try to minimize the data movement. Also for some + register classes bigger modes might be invalid, + e.g. DImode for AREG on x86. For such cases the + register move cost will be maximal. */ + mode = ALLOCNO_MODE (cp->second); + cost = (cp->second == allocno ? ira_register_move_cost[mode][rclass][aclass] : ira_register_move_cost[mode][aclass][rclass]); @@ -1512,7 +1522,7 @@ update_conflict_hard_regno_costs (int *costs, enum reg_class aclass, index = ira_class_hard_reg_index[aclass][hard_regno]; if (index < 0) continue; - cost = (int) ((unsigned) conflict_costs [i] * mult) / div; + cost = (int) (((long) conflict_costs [i] * mult) / div); if (cost == 0) continue; cont_p = true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b0c764f3949..44a34f985e6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-04-05 Vladimir Makarov + + PR rtl-optimization/70703 + * gcc.target/i386/pr70703.c: New. + 2017-04-05 Jakub Jelinek PR sanitizer/80308 diff --git a/gcc/testsuite/gcc.target/i386/pr70703.c b/gcc/testsuite/gcc.target/i386/pr70703.c new file mode 100644 index 00000000000..d0950aec19d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr70703.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-final { scan-assembler "movl\t\\\$6700417, %eax" } } */ + +unsigned ud_x_641_mul(unsigned x) { + /* optimized version of x / 641 */ + return ((unsigned long long)x * 0x663d81) >> 32; +}