cpetito 0 Posted May 18, 2010 Report Share Posted May 18, 2010 Bug description: Compiler seems to produce incorrect output when comparing an unsigned long with a unsigned char. Steps to reproduce: The following code was extracted from a larger project and compiled. I believe that the compiler output for the compare is not correct and the compare does not evaluate as expected. #include <system.h> //Target PIC18F458 configuration word #pragma DATA _CONFIG1H, _OSCS_OFF_1H & _HS_OSC_1H #pragma DATA _CONFIG2L, _BOR_OFF_2L & _PWRT_OFF_2L #pragma DATA _CONFIG2H, _WDT_OFF_2H #pragma DATA _CONFIG4L, _DEBUG_OFF_4L & _LVP_ON_4L & _STVR_ON_4L #pragma DATA _CONFIG5L, _CP3_OFF_5L & _CP2_OFF_5L & _CP1_OFF_5L & _CP0_OFF_5L #pragma DATA _CONFIG5H, _CPD_OFF_5H & _CPB_OFF_5H #pragma DATA _CONFIG6L, _WRT3_OFF_6L & _WRT2_OFF_6L & _WRT1_OFF_6L & _WRT0_OFF_6L #pragma DATA _CONFIG6H, _WRTD_OFF_6H & _WRTB_OFF_6H & _WRTC_OFF_6H #pragma DATA _CONFIG7L, _EBTR3_OFF_7L & _EBTR2_OFF_7L & _EBTR1_OFF_7L & _EBTR0_OFF_7L #pragma DATA _CONFIG7H, _EBTRB_OFF_7H //Set clock frequency #pragma CLOCK_FREQ 20000000 static unsigned long time; void test_compare(unsigned long time){ unsigned char monthLength; monthLength = 31; if (time >= monthLength) { time -= monthLength; } } void main( void ) { //Endless loop while( 1 ){ time = 133; test_compare(time); } } Here is the compiler output: if (time >= monthLength) { 000C 5009 MOVF test_compa_00009_1_monthLength, W 000E 6E0A MOVWF CompTempVar592 0010 6A0B CLRF CompTempVar592+D'1' 0012 6A0C CLRF CompTempVar592+D'2' 0014 6A0D CLRF CompTempVar592+D'3' 0016 5C08 SUBWF test_compa_00009_arg_time+D'3', W 0018 E108 BNZ label1 001A 500C MOVF CompTempVar592+D'2', W 001C 5C07 SUBWF test_compa_00009_arg_time+D'2', W 001E E105 BNZ label1 0020 500B MOVF CompTempVar592+D'1', W 0022 5C06 SUBWF test_compa_00009_arg_time+D'1', W 0024 E102 BNZ label1 0026 500A MOVF CompTempVar592, W 0028 5C05 SUBWF test_compa_00009_arg_time, W 002A label1 002A A0D8 BTFSS STATUS,C It appears that W is not properly initialized prior to the the first SUBWF at 0x0016. And for a variation, if monthLength is cast as an unsigned long. note that additionally at 0x0014 CompTempVar593+D'3' is cleared and not CompTempVar592+D'3' as expected.: if (time >= (unsigned long)monthLength) { 000C 5009 MOVF test_compa_00009_1_monthLength, W 000E 6E0A MOVWF CompTempVar592 0010 6A0B CLRF CompTempVar592+D'1' 0012 6A0C CLRF CompTempVar592+D'2' 0014 6A11 CLRF CompTempVar593+D'3' 0016 5C08 SUBWF test_compa_00009_arg_time+D'3', W 0018 E108 BNZ label1 001A 500C MOVF CompTempVar592+D'2', W 001C 5C07 SUBWF test_compa_00009_arg_time+D'2', W 001E E105 BNZ label1 0020 500B MOVF CompTempVar592+D'1', W 0022 5C06 SUBWF test_compa_00009_arg_time+D'1', W 0024 E102 BNZ label1 0026 500A MOVF CompTempVar592, W 0028 5C05 SUBWF test_compa_00009_arg_time, W 002A label1 002A A0D8 BTFSS STATUS,C However if we cast both operands as unsigned ints, the code is as expected, Register W is initialized prior to the first SUBWF: if ((unsigned int)time >= (unsigned int)monthLength) { 000C 5009 MOVF test_compa_00009_1_monthLength, W 000E 6E0A MOVWF CompTempVar592 0010 6A0B CLRF CompTempVar592+D'1' 0012 500A MOVF CompTempVar592, W 0014 5C05 SUBWF test_compa_00009_arg_time, W 0016 500B MOVF CompTempVar592+D'1', W 0018 6206 CPFSEQ test_compa_00009_arg_time+D'1' 001A 5C06 SUBWF test_compa_00009_arg_time+D'1', W 001C A0D8 BTFSS STATUS,C Expected behaviour: With the values assigned to time and monthLength, I expected that the expression would have evaluated true and executed the statement: time -= monthLength; Is the problem 100% reproduceable: Yes IDE version: SourceBoost IDE version Compiler: BoostC Compiler version: V6.97 Release Candidate 4 Target device: PIC18F458 OS: Windows VISTA Professional 64bit Comments: I believe that the code worked as expected with SourceBoostC V6.96. I decided to reinstall because I was having simulation issues with the SourceBoost IDE. I reinstalled with the latest RC to see if it corrected the simulation issues. It appears that the simulation issues are resolved, but then I discovered the above issue. I did not back down to V6.96 to verify. Quote Link to post Share on other sites
Pavel 0 Posted May 20, 2010 Report Share Posted May 20, 2010 Problem confirmed. Will investigate asap. Thanks for reporting. Regards, Pavel Quote Link to post Share on other sites
Pavel 0 Posted May 20, 2010 Report Share Posted May 20, 2010 This problem is caused by over-optimisation. We still work on a fix. Meanwhile please use a workaround: use level 1 optimisation (compiler command line argument -O1) Regards, Pavel Quote Link to post Share on other sites
cpetito 0 Posted May 20, 2010 Author Report Share Posted May 20, 2010 This problem is caused by over-optimisation. We still work on a fix. Meanwhile please use a workaround: use level 1 optimisation (compiler command line argument -O1) Regards, Pavel Thank you for the very prompt response. You folks are exceptional! Regards, Carl Quote Link to post Share on other sites
Dave 0 Posted May 28, 2010 Report Share Posted May 28, 2010 Bug description:Compiler seems to produce incorrect output when comparing an unsigned long with a unsigned char. This problem has been fixed in V6.97 RC5. You can download it from here: http://www.sourceboost.com/CommonDownload.html Regards Dave Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.