Jump to content

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.

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

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

Link to post
Share on other sites

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.

Guest
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...
×
×
  • Create New...