Menu ▾ ▴

#1039 Unnecessary promotion generates sub-optimal code

None
open
nobody
None
5
2026-10-27
2026-10-27
No

The following code:

unsigned char buf[16];

void func(void)
{
  unsigned int count;
  count=16;

  do {
    buf[count]=1;
    count--;
  } while(count);

}

generates:

    ldy #0x10
00101$:
    tya
    tax
    lda #0x01
    sta (_buf+0x0000+0),x
    dey
    bne 00101$
    rts

instead of:

    ldy #0x10
    lda #0x01
00101$:
    sta (_buf+0x0000+0),y
    dey
    bne 00101$
    rts

the optimizer correctly narrows down count to _Bitint(8), but then insists in copying it to a pointer (IC5) before using it as an index for IC6:

;------------------------------------------------------------
;Allocation info for local variables in function 'func'
;------------------------------------------------------------
;count         Allocated to registers 
;------------------------------------------------------------
;   memset8.c: 3: void func(void)
;    [---] ic:0:  _entry($5) :
;    [---] ic:1:    proc _func [k1 lr0:0 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{void function (void ) fixed}
;   -----------------------------------------
;    function func
;   -----------------------------------------
;   Register assignment is optimal.
;   Stack space usage: 0 bytes.
_func:
;   memset8.c: 9: do {
;    [---] ic:4:    iTemp1 [k5 lr3:10 so:0]{ ia0 a2p0 re0 rm1 nos0 ru0 dp0 oe0 myp0}{unsigned-char __xdata* fixed}[remat] = &[_buf [k4 lr0:0 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-char [16] __xdata} , 0x0 {const-unsigned-char literal}]
;   skipping iCode since result will be rematerialized
;    [---] ic:18:   iTemp4 [k8 lr4:10 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-_BitInt(8) register}[y ] := 0x10 {unsigned-_BitInt(8) literal}
    ldy #0x10   ; A:--:???  X:--:???  Y:--:???  F:y C:?
;    [-y-] ic:3:  _dobody_0($1) :
00101$:
;   memset8.c: 10: buf[count]=1;
;    [-y-] ic:5:    iTemp2 [k6 lr7:8 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-char __xdata* fixed}[a x ] := iTemp4 [k8 lr4:10 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-_BitInt(8) register}[y ]
; Peephole dead LX1 - removed dead ldx #0x00
    tya     ; A:--:???  X:U-:#00  Y:UL:???  F:a C:?
;    [-y-] ic:6:    *(iTemp2 [k6 lr7:8 so:0]{ ia1 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-char __xdata* fixed}[a x ]) := 0x1 {unsigned-char literal}
    tax     ; A:U-:???  X:--:#00  Y:UL:???  F:x C:?
    lda #0x01   ; A:U-:???  X:U-:???  Y:UL:???  F:a C:?
    sta (_buf+0x0000+0),x   ; A:U-:#01  X:U-:???  Y:UL:???  F:a C:?
;   memset8.c: 11: count--;
;    [---] ic:8:    iTemp4 [k8 lr4:10 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-_BitInt(8) register}[y ] = iTemp4 [k8 lr4:10 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-_BitInt(8) register}[y ] - 0x1 {unsigned-_BitInt(8) literal}
    dey     ; A:--:#01  X:--:???  Y:U-:???  F:y C:?
;   memset8.c: 12: } while(count);
;    [-y-] ic:11:   if iTemp4 [k8 lr4:10 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{unsigned-_BitInt(8) register}[y ] != 0 goto _dobody_0($1)
    bne 00101$
;    [---] ic:14:  _return($4) :
;   memset8.c: 14: }
;    [---] ic:15:   eproc _func [k1 lr0:0 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0 oe0 myp0}{void function (void ) fixed}
    rts     ; A:--:???  X:--:???  Y:--:???  F:? C:?

Discussion


Log in to post a comment.