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

            Bug ID: 83805
           Summary: Wrong constant merging for objects in different
                    address spaces
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

Compile the following code with

$ avr-gcc -Os bug.c -S -mmcu=avr5

char fun1 (unsigned i)
{
  static const __flash char str1[] = "0123456789";
  __asm ("; " :: "r" (str1));
  return str1[i];
}

char fun2 (unsigned i)
{
  static const char str2[] = "0123456789";
  __asm ("; " :: "r" (str2));
  return str2[i];
}


str1 and str2 reside in different address spaces, and they should end up in
different sections; namely str1 in flash (.progmem.data) which is the case, and
str2 in RAM (.rodata) which is not the case.

Instead, the two objects are merged together in .LC0:

.section        .progmem.data.str1.1,"aMS",@progbits,1
.LC0:
        .string "0123456789"
        .text

fun1:
        ldi r18,lo8(str1.1511)
        ldi r19,hi8(str1.1511)
/* #APP */
        ; 
/* #NOAPP */
        movw r30,r24
        subi r30,lo8(-(.LC0))
        sbci r31,hi8(-(.LC0))
        lpm r24,Z
        ret

fun2:
        ldi r18,lo8(str2.1515)
        ldi r19,hi8(str2.1515)
/* #APP */
        ; 
/* #NOAPP */
        movw r30,r24
        subi r30,lo8(-(.LC0))
        sbci r31,hi8(-(.LC0))
        ld r24,Z
        ret
.section        .rodata
str2.1515:
        .string "0123456789"
.section        .progmem.data,"a",@progbits
str1.1511:
        .string "0123456789"

Hence .LC0 is once accessed by LPM (which can only access flash but not RAM)
and once by LD (which can only access RAM but not flash)

Moreover, there are three(!) instances of the string "0123456789" where two
would be enough (one in flash, one in RAM).

Reply via email to