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

--- Comment #5 from Georg-Johann Lay <gjl at gcc dot gnu.org> ---
Created attachment 65720
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65720&action=edit
pr126179.c: GNU-C99 test case

(In reply to Richard Biener from comment #4)
> But this looks sound, so I'm not sure what exactly the problem is to date
> (maybe trunk no longer exhibits the original issue)?
As far as I can tell, the test case above doesn't fail, but the case from
PR126179 fails:

struct pair { unsigned char data; unsigned char cmd; };
const __flash struct pair table[] = { {0x11, 1}, {0x33, 0}, {0x55,1} };

void write_data (unsigned char d);
void write_cmd (unsigned char c);

void test (void)
{
    unsigned char i;
    for (i = 0; i < 3; i++)
    {
        if (table[i].cmd)
            write_data (table[i].data);
        else
            write_cmd (table[i].data);
    }
}

$ avr-gcc pr126179.c -S -Os -mmcu=atmega8 -dp -da -v

GNU C23 (GCC) version 17.0.0 20260925 (experimental) (avr)

The generated asm reads:

test:
        push r16                 ;  54  [c=4 l=1]  pushqi1/0
        push r17                 ;  55  [c=4 l=1]  pushqi1/0
        push r28                 ;  56  [c=4 l=1]  pushqi1/0
        ldi r16,lo8(table)       ;  52  [c=4 l=2]  *movhi/4
        ldi r17,hi8(table)
        ldi r28,lo8(3)   ;  53  [c=4 l=1]  movqi_insn/1
.L4:
        movw r30,r16     ;  67  [c=4 l=1]  *movhi/0
        ld r24,Z+                ;  48  [c=4 l=1]  movqi_insn/3
        lpm r25,Z        ;  49  [c=4 l=1]  movqi_insn/3

where insn 48 reads from AS0 (using ld) but should read from AS1 (using lpm).
In the .expand dump there is:

void test ()
{
  unsigned short ivtmp.12;
  unsigned char _2;
  unsigned char ivtmp_3;
  unsigned char ivtmp_4;
  unsigned char pretmp_7;
  unsigned short _16;
  unsigned short _17;
  const <address-space-1> struct pair[3] * _22;
  void * _23;

;;   basic block 2, loop depth 0
;;    pred:       ENTRY
  ivtmp.12_12 = (unsigned short) &table;   <--BUG: AS1 is lost
;;    succ:       3

;;   basic block 3, loop depth 1
;;    pred:       6
;;                2
  # ivtmp_4 = PHI <ivtmp_3(6), 3(2)>
  # ivtmp.12_5 = PHI <ivtmp.12_13(6), ivtmp.12_12(2)>
  _16 = ivtmp.12_5 + 1;
  _17 = _16 - ivtmp.12_12;
  _22 = &table + _17;
  _2 = MEM[(unsigned char *)_22];
  _23 = (void *) ivtmp.12_5;
  pretmp_7 = MEM[(unsigned char *)_23];
  if (_2 != 0)
    goto <bb 4>; [50.00%]
  else
    goto <bb 5>; [50.00%]

I am not completely sure that the dump shows the real thing. AFAIR the tree
dump may miss address-space qualifiers, so you must take the dump with a grain
of salt.

Anyways, the generated RTL is wrong:

;; pretmp_7 = MEM[(unsigned char *)_23];

(insn 9 8 0 (set (reg:QI 46 [ pretmp_7 ])
        (mem:QI (reg:HI 45 [ ivtmp.12 ]) [0 MEM[(unsigned char *)_23]+0 S1
A8])) "pr126179.c":13:33 -1
     (nil)) <--BUG: Misses AS1

The other access is ok:

(insn 13 12 14 (set (reg:QI 55)
        (mem:QI (reg:HI 54 [ _22 ]) [0 MEM[(unsigned char *)_22]+0 S1 A8 AS1]))
"pr126179.c":12:12 -1
     (nil))  <--OK: has AS1

Reply via email to