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? 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