On January 9, 2018 12:59:04 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >SMS is done before reload and assumes it can extend the lifetime by >making >copies of the destination registers without trying to re-recognize the >instructions etc. That can work only with pseudos, for some hard >registers >there isn't even a valid move instruction to pseudo (e.g. the powerpc >CA >register), for others it can be very much undesirable. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. >2018-01-09 Jakub Jelinek <ja...@redhat.com> > > PR target/83507 > * modulo-sched.c (schedule_reg_moves): Punt if we'd need to move > hard registers. Formatting fixes. > > * gcc.dg/sms-13.c: New test. > >--- gcc/modulo-sched.c.jj 2018-01-03 10:19:55.710534046 +0100 >+++ gcc/modulo-sched.c 2018-01-08 16:53:01.232465389 +0100 >@@ -687,9 +687,9 @@ schedule_reg_moves (partial_schedule_ptr > rtx set = single_set (u->insn); > > /* Skip instructions that do not set a register. */ >- if ((set && !REG_P (SET_DEST (set)))) >+ if (set && !REG_P (SET_DEST (set))) > continue; >- >+ > /* Compute the number of reg_moves needed for u, by looking at life > ranges started at u (excluding self-loops). */ > distances[0] = distances[1] = false; >@@ -743,7 +743,10 @@ schedule_reg_moves (partial_schedule_ptr > first_move += ps->g->num_nodes; > > /* Generate each move. */ >- old_reg = prev_reg = SET_DEST (single_set (u->insn)); >+ old_reg = prev_reg = SET_DEST (set); >+ if (HARD_REGISTER_P (old_reg)) >+ return false; >+ > for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++) > { > ps_reg_move_info *move = ps_reg_move (ps, first_move + i_reg_move); >--- gcc/testsuite/gcc.dg/sms-13.c.jj 2018-01-08 17:00:16.427534076 >+0100 >+++ gcc/testsuite/gcc.dg/sms-13.c 2018-01-08 16:56:15.704496101 +0100 >@@ -0,0 +1,32 @@ >+/* PR target/83507 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -fmodulo-sched -fno-tree-ter >-fno-tree-coalesce-vars" } */ >+ >+void >+foo (unsigned short int x, unsigned char y) >+{ >+ unsigned char *a = &y; >+ unsigned short int b; >+ int c; >+ >+ while (y < 3) >+ { >+ if (x != 0) >+ ++y; >+ ++y; >+ } >+ >+ for (c = 0; c < 5; ++c) >+ { >+ int d = 1; >+ d += b > x; >+ y &= d; >+ } >+ >+ do >+ { >+ c += y; >+ x = c; >+ } >+ while (x != 0); >+} > > Jakub