Skip to content

clang generates incorrect code when storing to memory location 0x1 for target avr-none #143247

@tomtor

Description

@tomtor

sample code:

#define PA      0x1 // Bad
//#define PA    0x2 // Good

volatile char *const PORT = (char *const) PA;

extern void nil(short);

void bug()
{
  short s= 0;
 
  while (1) {
    s++;
    *PORT = *PORT | 0x80;
    nil((s & 0xF) + 1);
  }
}

compiled with clang build from git yesterday:

clang -O2 -target avr-none -mmcu=attiny402 -S bug.c

generates an incorrect load (from 0x0 via X+) and store (uses expression based on s which changes in each loop iteration instead of constant 0x1):

bug:                                    ; @bug
; %bb.0:                                ; %entry
        push    r16
        push    r17
        ldi     r26, 0
        ldi     r27, 0
.LBB0_1:                                ; %while.cond
                                        ; =>This Inner Loop Header: Depth=1
        ld      r24, X+
        ori     r24, -128
        movw    r16, r26
        andi    r26, 15
        andi    r27, 0
        st      X+, r24
        movw    r24, r26
        call    nil
        movw    r26, r16
        rjmp    .LBB0_1

using #define PA 0x2

generates correct code with sbi instruction:

bug:                                    ; @bug
; %bb.0:                                ; %entry
        push    r16
        push    r17
        ldi     r24, 0
        ldi     r25, 0
.LBB0_1:                                ; %while.cond
                                        ; =>This Inner Loop Header: Depth=1
        sbi     2, 7
        adiw    r24, 1
        movw    r16, r24
        andi    r24, 15
        andi    r25, 0
        adiw    r24, 1
        call    nil
        movw    r24, r16
        rjmp    .LBB0_1

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions