#2241 wrong code generated for a function call inside nested loops

open
nobody
None
redundancy elimination
7
2015-02-16
2014-01-17
mz-fuzzy
No

Following source generates wrong asm code:

int fn(int p1);

int main(int argc, char *argv[])
{
    int i, j;
    char *p;

    for (i = 1; i < argc; ++i) {
        p = argv[i];
    }
    if (i < argc) {
        for (; i < argc; ++i) {
            p = argv[i];
        }
    }
    else {
        for (i = 0; i < 8; ++i)
            for (j = 0; j < 8; ++j) 
                fn(i*8+j);
    } 
    return 0;
}

The problem is the code generated for "fn(i*8+j)":

                             88 ;sdccerr.c:17: for (i = 0; i < 8; ++i)
   0030                      89 00126$:
   0030 01 00 00      [10]   90         ld      bc,#0x0000
                             91 ;sdccerr.c:18: for (j = 0; j < 8; ++j)
   0033                      92 00124$:
   0033 21 00 00      [10]   93         ld      hl,#0x0000
   0036                      94 00114$:
                             95 ;sdccerr.c:19: fn(i*8+j);
   0036 E5            [11]   96         push    hl
   0037 C5            [11]   97         push    bc
   0038 E5            [11]   98         push    hl
   0039 CDr00r00      [17]   99         call    _fn
   003C F1            [10]  100         pop     af
   003D C1            [10]  101         pop     bc
   003E E1            [10]  102         pop     hl
                            103 ;sdccerr.c:18: for (j = 0; j < 8; ++j)
   003F 23            [ 6]  104         inc     hl
   0040 7D            [ 4]  105         ld      a,l
   0041 D6 08         [ 7]  106         sub     a, #0x08
   0043 7C            [ 4]  107         ld      a,h
   0044 17            [ 4]  108         rla
   0045 3F            [ 4]  109         ccf
   0046 1F            [ 4]  110         rra
   0047 DE 80         [ 7]  111         sbc     a, #0x80
   0049 38 EB         [12]  112         jr      C,00114$
                            113 ;sdccerr.c:17: for (i = 0; i < 8; ++i)
   004B 03            [ 6]  114         inc     bc
   004C 79            [ 4]  115         ld      a,c
   004D D6 08         [ 7]  116         sub     a, #0x08
   004F 78            [ 4]  117         ld      a,b
   0050 17            [ 4]  118         rla
   0051 3F            [ 4]  119         ccf
   0052 1F            [ 4]  120         rra
   0053 DE 80         [ 7]  121         sbc     a, #0x80
   0055 38 DC         [12]  122         jr      C,00124$
   0057                     123 00107$:

in line #98, hl is pushed into stack as the fn parameter - and it seems that hl contains only 'j' counter. This is wrong, 'i*8+j' should be there.

SDCC : z80 3.3.2 #8937 (Jan 14 2014) (Linux)

1 Attachments

Discussion

    • Priority: 5 --> 7
     
  • Increasing priority, since bad code is generated silently.

    Philipp

     
    • Category: other --> redundancy elimination
     
  • This bug is not z80-specific (I can reproduce it e.g. in the stm8 port).
    It seems this is a gcse bug: The problem goes away when compiling using --nogcse.

    Philipp

     
  • The bug is introduced into the iCode when we run gcse for the second time (after the loop optimization, before lospre). The code from dumploop looks good, but the code from dumploopg looks broken.

    Philipp