https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120423

--- Comment #1 from Georg-Johann Lay <gjl at gcc dot gnu.org> ---
Created attachment 61553
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61553&action=edit
Reduced C test case

Here is a reduced C test case:

struct data
{
    int a;
    int b;
};

unsigned char val;

void func (struct data *d)
{
    d->a = 0;
    d->b = 256 * val - 1;
}

$ avr-gcc-15 pr120423-2.c -S -Os -mmcu=atmega8 -mno-lra
pr120423-2.c: In function 'func':
pr120423-2.c:13:1: error: insn does not satisfy its constraints:
   13 | }
      | ^
(insn 9 18 10 2 (set (reg:HI 18 r18 [orig:50 _3 ] [50])
        (ashift:HI (reg:HI 31 r31)
            (const_int 8 [0x8]))) "pr120423-2.c":12:16 667 {ashlhi3}
     (nil))
during RTL pass: postreload
pr120423-2.c:13:1: internal compiler error: in extract_constrain_insn, at
recog.cc:2783

Modes > 8 bits like HImode should never ever go into an odd register, see
avr.cc:

static bool
avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  [...]
  /* Any GENERAL_REGS register can hold 8-bit values.  */

  if (GET_MODE_SIZE (mode) == 1)
    return true;

  /* FIXME: Ideally, the following test is not needed.
        However, it turned out that it can reduce the number
        of spill fails.  AVR and it's poor endowment with
        address registers is extreme stress test for reload.  */

  if (GET_MODE_SIZE (mode) >= 4
      && regno >= REG_X
      // This problem only concerned the old reload.
      && ! avropt_lra_p)
    return false;

  /* All modes larger than 8 bits should start in an even register.  */

  return !(regno & 1);
}

Reply via email to