Index: ChangeLog =================================================================== --- ChangeLog (revision 246706) +++ ChangeLog (working copy) @@ -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 Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 246706) +++ testsuite/ChangeLog (working copy) @@ -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 Index: ira-color.c =================================================================== --- ira-color.c (revision 246536) +++ ira-color.c (working copy) @@ -1367,6 +1367,16 @@ update_costs_from_allocno (ira_allocno_t || 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 *c 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; Index: testsuite/gcc.target/i386/pr70703.c =================================================================== --- testsuite/gcc.target/i386/pr70703.c (nonexistent) +++ testsuite/gcc.target/i386/pr70703.c (working copy) @@ -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; +}