CCES compiler problem

Hi,

I have the strange behaviour of my program.
It runs correctly when an optimization is off: at the
end the printed values of "buf" and "should be" are the same.

When an optimization is on (options -O -Ov100), the printed values
of "buf" and "should be" are different.

Looking at the assembler code I see that compiler adds 13
instead of "bpc" during each cycle iteration.

I've tried to reduce optimization level to 85 (option -Ov85) and
result is the same.

I've tried to compile this program using Visual DSP for BlackFin 532 and
CrossCore for BlackFin 609. Result is the same.


Here is the source code:

#include <stdio.h>
#include <stdint.h>

int go(unsigned int bpc, size_t units) {
    uint8_t buffer[32] = "abc";

    uint8_t *buf = buffer;
    uint8_t *end = buf + units * bpc;

    long lb = 0;
    long ub = 127;
    long ch;
    long value = 0;

    int my_cnt=0;

    ub -= lb;

    for(; my_cnt < 2;)
    {
        
        if (13 == bpc) {
            //value = *(buf + 1) | *buf;
            value = *(buf + 0) | my_cnt | *(buf + 1);
        }

        ch = value - lb;

        printf("ch=%i, value=%i\n", ch, value);

        
        if(ch < 0) {
            return -1;
        }

        my_cnt++;

        buf = buf + bpc;
    }

    printf("start  buffer: %08X\n", buffer);
    printf("          buf: %08X\n", buf);
    printf("    should be: %08X\n", buffer + bpc*2);
    //printf("OCTET_STRING_per_put_characters: my_cnt=%d\n", my_cnt);
    //printf("OCTET_STRING_per_put_characters: for ub=%ld, lb=%ld, buf=%08X, end=%08X, bpc=%d\n", ub, lb, buf, end, bpc);
    return 0;
}


int main( int argc, char *argv[] )
{
    
    go(1, 4);
	return 0;
}

What should I do to avoid this strange behaviour?
Please, don't say "do not use optimization" or "decrease optimization level", it is not my case.

  • 0
    •  Analog Employees 
    on Sep 1, 2021 2:40 PM

    Thank you very much for the report. We confirmed that this is a compiler problem, and aim to fix it in the next update. The compiler notices that 'buf' is only dereferenced inside the if(13 == bpc) condition, and hence infers that it can just increment it by 13 in the loop steps rather than by 'bpc'. That's fine, but it then wrongly uses the resulting 'buf' value outside the loop.

    One workaround is to move one of the 'buf' dereferences outside the condition, for example:

            uint8_t buf0 = *buf;
        	if (13 == bpc) {
                value = buf0 | my_cnt | *(buf + 1);
            }