Menu

#3626 Necessary cases are deleted in switch

closed-fixed
None
redundancy elimination
5
2023-07-29
2023-07-28
kwhr00
No

Here is the source that can reproduce the bug.

#include <stdio.h>

void main(void) {
    unsigned char state = 0;
    while (1) {
        putchar(state + '0');
        switch (state) {
            case  0: state = 1; break;
            case  1: state = 2; break;
            case  2: state = 3; break;
            case  3: state = 4; break;
            case  4: state = 5; break;
            default: state = 0; break;
        }
    }
}

When compiling with sdcc 4.3.0, the following warnings are displayed.

sdcc -c -mz80 test.c
test.c:7: warning 110: conditional flow changed by optimizer: so said EVELYN the modified DOG
test.c:9: warning 126: unreachable code
test.c:10: warning 126: unreachable code
test.c:11: warning 126: unreachable code
test.c:12: warning 126: unreachable code

The function part of test.lst looks like this:

      000000                         48 _main::
                                     49 ;test.c:4: unsigned char state = 0;
      000000 0E 00            [ 7]   50         ld      c, #0x00
                                     51 ;test.c:5: while (1) {
      000002                         52 00109$:
                                     53 ;test.c:6: putchar(state + '0');
      000002 59               [ 4]   54         ld      e, c
      000003 16 00            [ 7]   55         ld      d, #0x00
      000005 21 30 00         [10]   56         ld      hl, #0x0030
      000008 19               [11]   57         add     hl, de
      000009 C5               [11]   58         push    bc
      00000A CDr00r00         [17]   59         call    _putchar
      00000D C1               [10]   60         pop     bc
                                     61 ;test.c:7: switch (state) {
      00000E 3E 04            [ 7]   62         ld      a, #0x04
      000010 91               [ 4]   63         sub     a, c
      000011 38 04            [12]   64         jr      C, 00106$
                                     65 ;test.c:8: case 0: state = 1; break;
      000013 0E 01            [ 7]   66         ld      c, #0x01
      000015 18 EB            [12]   67         jr      00109$
                                     68 ;test.c:13: default: state = 0; break;
      000017                         69 00106$:
      000017 0E 00            [ 7]   70         ld      c, #0x00
                                     71 ;test.c:14: }
                                     72 ;test.c:16: }
      000019 18 E7            [12]   73         jr      00109$

Case 1 to 4 are gone.

Related

Wiki: NGI0-Entrust-SDCC

Discussion

  • Philipp Klaus Krause

    I can reproduce this in current trunk. --nogcse is a workaround.

    P.S.: However, this does no go wrong in the main call into GCSE from SDCCopt.c, but in one from data flow analysis, computeDataFlow in SDCCdflow.c.

    P.P.S.: Apparently, the problem will only happen in a sequence like this:

    freeeBBlockData (ebbi);
    ebbi = iCodeBreakDown (ic);
    computeControlFlow (ebbi);
    loops = createLoopRegions (ebbi);
    computeDataFlow (ebbi);
    

    Multiple of them exist in SDCCopt.c, and if I skip one, the problem is triggered in the next.

     

    Last edit: Philipp Klaus Krause 2023-07-29
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
    • Category: Z80 --> redundancy elimination
     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
     
  • Philipp Klaus Krause

    Fixed in [r14246].

     

    Related

    Commit: [r14246]


Log in to post a comment.

MongoDB Logo MongoDB