Bug 56479 - Register allocator can't allocate two 4-byte variables into 8 registers for inline asm on avr-gcc
Summary: Register allocator can't allocate two 4-byte variables into 8 registers for i...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.7.2
: P5 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, ra
Depends on:
Blocks: 56183
  Show dependency treegraph
 
Reported: 2013-02-28 07:50 UTC by Denis Shulyaka
Modified: 2021-08-26 13:00 UTC (History)
0 users

See Also:
Host:
Target: avr
Build:
Known to work:
Known to fail: 3.4.6, 4.3.3, 4.5.2, 4.6.2, 4.7.2, 4.8.0
Last reconfirmed: 2013-03-02 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Denis Shulyaka 2013-02-28 07:50:56 UTC
Hi!

When I try to compile the following code with avr-gcc for atmega2560 cpu:

------------------------------------------------
#include <stdint.h>

uint64_t asmfoo(uint32_t x, uint32_t y);

int main(void)
{ return (int)asmfoo(1234, 5678); }

uint64_t asmfoo(uint32_t x, uint32_t y)
{
  uint64_t z;
  asm volatile (
  "nop \n\t" //I'm going to make use of fmul instructions here
  "nop \n\t" //which only accept r16-r23 registers
  "nop \n\t"
  : [Z]"=&r"(z)           //"r" is any general register (r1-r32)
  : [X]"a"(x), [Y]"a"(y)  //"a" is a simple upper register (r16-r23)
  );
  return z;
}
-------------------------------------------------

I get the following error:

$ avr-gcc-4.7.2 -c test.c
test.c: In function 'asmfoo':
test.c:13: error: can't find a register in class 'SIMPLE_LD_REGS' while reloading 'asm'
test.c:13: error: 'asm' operand has impossible constraints

I have tested it with 4.3.2 and 4.7.2 with different optimization levels.

On the other hand, the following code DOES compile:

-------------------------------------------------
#include <stdint.h>

uint64_t asmfoo(uint64_t x, uint32_t y);

int main(void)
{ return (int)asmfoo(1234, 5678); }

uint64_t asmfoo(uint64_t x, uint32_t y)  //       <-note the uint64_t
{
  uint64_t z;
  asm volatile (
  "nop \n\t"
  "nop \n\t"
  "nop \n\t"
  : [Z]"=&r"(z)
  : [X]"a"(x)          //                     <-note the absence of y
  );
  return z;
}
-------------------------------------------------
Comment 1 Georg-Johann Lay 2013-03-02 19:05:47 UTC
Confirmed with 4.8 from 2013-03-01 for any optimization level for the following, smaller test case:

void asmfoo (long x, long y)
{
    asm volatile ("" :: "a"(x), "a"(y));
}