re PR rtl-optimization/70703 (Regression in register usage on x86)
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 5 Apr 2017 15:07:51 +0000 (15:07 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 5 Apr 2017 15:07:51 +0000 (15:07 +0000)
2017-04-05  Vladimir Makarov  <vmakarov@redhat.com>

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  <vmakarov@redhat.com>

PR rtl-optimization/70703
* gcc.target/i386/pr70703.c: New.

From-SVN: r246707

gcc/ChangeLog
gcc/ira-color.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr70703.c [new file with mode: 0644]

index 0158a389ad7c658068f148da37ca35be53c67af1..951e0401ed1e9ff054b97497227f950c4decb8b9 100644 (file)
@@ -1,3 +1,10 @@
+2017-04-05  Vladimir Makarov  <vmakarov@redhat.com>
+
+       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  <jakub@redhat.com>
            Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
index ab981730ebaeec26c0c211045061a05893d27795..7886db4ffff38cfb6e7d25635c82400d7ffa0b53 100644 (file)
@@ -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;
index b0c764f3949d2b34fb53ea9db68ef8ae6a359bc1..44a34f985e60012e74cb5ccdb4b6d2bf48202b5e 100644 (file)
@@ -1,3 +1,8 @@
+2017-04-05  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/70703
+       * gcc.target/i386/pr70703.c: New.
+
 2017-04-05  Jakub Jelinek  <jakub@redhat.com>
 
        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 (file)
index 0000000..d0950ae
--- /dev/null
@@ -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;
+}