Hi,
I had a deadlock problem in my current project und reduced the issue to the following code snippet, which results in
A: an endless loop when compiling with:
$ sdcc -S test.c
test.c:17: warning 110: conditional flow changed by optimizer: so said EVELYN the modified DOG
B: it gives a strange warning when compiling with
$ sdcc --nolabelopt -S test.c
test.c:15: warning 126: unreachable code
C: and works with
$ sdcc --nogcse -S test.c
Compiler version is "Version 3.5.0 #9253 (Mar 24 2016) (Linux)"
File: test.c
#include <stdint.h>
uint8_t in[4],out[4];
uint8_t type;
void main(void) {
uint8_t i;
uint8_t len = 2;
switch(in[0]) {
case 0x01:
for(i=0;i<len;i++) {
out[i] = in[i];
}
break;
case 0x02:
for(i=0;i<4;i++) {
out[i] = in[i];
}
break;
}
}
And the output of "test.asm" when compiling with "sdcc -S test.c":
;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.5.0 #9253 (Mar 24 2016) (Linux)
; This file was generated Sat Apr 21 10:31:47 2018
;--------------------------------------------------------
.module test
.optsdcc -mmcs51 --model-small
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
.globl _main
.globl _type
.globl _out
.globl _in
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
.area RSEG (ABS,DATA)
.org 0x0000
;--------------------------------------------------------
; special function bits
;--------------------------------------------------------
.area RSEG (ABS,DATA)
.org 0x0000
;--------------------------------------------------------
; overlayable register banks
;--------------------------------------------------------
.area REG_BANK_0 (REL,OVR,DATA)
.ds 8
;--------------------------------------------------------
; internal ram data
;--------------------------------------------------------
.area DSEG (DATA)
_in::
.ds 4
_out::
.ds 4
_type::
.ds 1
;--------------------------------------------------------
; overlayable items in internal ram
;--------------------------------------------------------
.area OSEG (OVR,DATA)
;--------------------------------------------------------
; Stack segment in internal ram
;--------------------------------------------------------
.area SSEG
__start__stack:
.ds 1
;--------------------------------------------------------
; indirectly addressable internal ram data
;--------------------------------------------------------
.area ISEG (DATA)
;--------------------------------------------------------
; absolute internal ram data
;--------------------------------------------------------
.area IABS (ABS,DATA)
.area IABS (ABS,DATA)
;--------------------------------------------------------
; bit data
;--------------------------------------------------------
.area BSEG (BIT)
;--------------------------------------------------------
; paged external ram data
;--------------------------------------------------------
.area PSEG (PAG,XDATA)
;--------------------------------------------------------
; external ram data
;--------------------------------------------------------
.area XSEG (XDATA)
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
.area XABS (ABS,XDATA)
;--------------------------------------------------------
; external initialized ram data
;--------------------------------------------------------
.area XISEG (XDATA)
.area HOME (CODE)
.area GSINIT0 (CODE)
.area GSINIT1 (CODE)
.area GSINIT2 (CODE)
.area GSINIT3 (CODE)
.area GSINIT4 (CODE)
.area GSINIT5 (CODE)
.area GSINIT (CODE)
.area GSFINAL (CODE)
.area CSEG (CODE)
;--------------------------------------------------------
; interrupt vector
;--------------------------------------------------------
.area HOME (CODE)
__interrupt_vect:
ljmp __sdcc_gsinit_startup
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
.area HOME (CODE)
.area GSINIT (CODE)
.area GSFINAL (CODE)
.area GSINIT (CODE)
.globl __sdcc_gsinit_startup
.globl __sdcc_program_startup
.globl __start__stack
.globl __mcs51_genXINIT
.globl __mcs51_genXRAMCLEAR
.globl __mcs51_genRAMCLEAR
.area GSFINAL (CODE)
ljmp __sdcc_program_startup
;--------------------------------------------------------
; Home
;--------------------------------------------------------
.area HOME (CODE)
.area HOME (CODE)
__sdcc_program_startup:
ljmp _main
; return from main will return to caller
;--------------------------------------------------------
; code
;--------------------------------------------------------
.area CSEG (CODE)
;------------------------------------------------------------
;Allocation info for local variables in function 'main'
;------------------------------------------------------------
;i Allocated to registers
;len Allocated to registers
;------------------------------------------------------------
; test.c:6: void main(void) {
; -----------------------------------------
; function main
; -----------------------------------------
_main:
ar7 = 0x07
ar6 = 0x06
ar5 = 0x05
ar4 = 0x04
ar3 = 0x03
ar2 = 0x02
ar1 = 0x01
ar0 = 0x00
; test.c:10: switch(in[0]) {
mov r7,_in
cjne r7,#0x01,00130$
sjmp 00116$
00130$:
; test.c:12: for(i=0;i<len;i++) {
cjne r7,#0x02,00111$
sjmp 00117$
00116$:
mov r6,#0x00
00107$:
cjne r6,#0x02,00132$
00132$:
jnc 00111$
; test.c:13: out[i] = in[i];
mov a,r6
add a,#_out
mov r1,a
mov a,r6
add a,#_in
mov r0,a
mov ar5,@r0
mov @r1,ar5
; test.c:12: for(i=0;i<len;i++) {
inc r6
; test.c:17: for(i=0;i<4;i++) {
sjmp 00107$
00117$:
00109$:
; test.c:18: out[i] = in[i];
mov _out,r7
; test.c:17: for(i=0;i<4;i++) {
; test.c:21: }
sjmp 00109$
00111$:
ret
.area CSEG (CODE)
.area CONST (CODE)
.area XINIT (CODE)
.area CABS (ABS,CODE)
Works for me using sdcc compiled from current trunk on Debian GNU/Linux testing on amd64.
Please reopen if you can still reproduce the issue using current sdcc.