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.
I can reproduce this in current trunk.
--nogcseis 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:
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
Fixed in [r14246].
Related
Commit: [r14246]