Jump to content
Sign in to follow this  
cpetito

Compiler Problem With Unsigned Long Compare

Recommended Posts

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.

Share this post


Link to post
Share on other sites

Problem confirmed. Will investigate asap. Thanks for reporting.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×