This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28335: local variable value is wrong on 4.1.3 compiler except add volatile in front

Part Number: TMS320F28335

Tool/software: Code Composer Studio

Hi

CCS 3.3.82.13

Compiler 4.1.3 

For below local variable all and half.

1. The value in debugging environment is right only if we add volatile in front of variable or none optimize.

int64 half2quan(int32 target,int64 now, Uint16 Axis)
{
volatile
 int64 all,half;
 int64 TMP;
// long lsd;
// lsd=0x80000000;
// min=(int64)lsd*Position_Numerator1/Position_Divisor1;
// lsd=0x7fffffff;
// max=(long long)lsd*Position_Numerator1/Position_Divisor1;
// half=(int64)0x80000000;
// half=(int64)half*Position_Numerator1/Position_Divisor1;
 all=(int64)0x100000000;
 all=(int64)all*Position_Numerator1/Position_Divisor1;
 half=all;
 half=half>>1;//((int64)all>>1);
 TMP = (int64)target*Position_Numerator1/Position_Divisor1-now;

 if(TMP>half) TMP-=all;
 else if(TMP<-half) TMP+=all;
 return TMP;
}

2. if set optimize level to 3 or remove volatile. The value is wrong.

Could you let me know does it caused by old compiler ? Why should we must add volatile for a local variable? Thanks.

  • Daniel Fang said:
    Compiler 4.1.3 

    That compiler is over 10 years old.  Please upgrade.  I cannot guarantee that upgrading fixes your problem.  But I think your chances are good.

    You might consider using a newer compiler with that old CCS 3.3.  That combination has not been tested.  It often works.  But the farther apart in time the releases of CCS and the compiler, the more likely it is a problem will occur.

    To understand how your problem occurred, I need to reproduce it.  I don't need to run the code.  I can usually see the problem by inspecting the assembly code generated by the compiler.  Please submit a test case, by using these steps.

    1. Preprocess the source file which contains the function half2quan
    2. Attach that to your next post
    3. Show all the compiler options exactly as the compiler sees them

    Thanks and regards,

    -George

  • Hello George,

    Do you mean you are still not sure it's caused by CCS or compiler version? Is there any early log fix on this before?

    Why it can be avoided by must add volatile? We are very worry about on other variables.

    What's the test case you need? Could you kindly give some more hints on this? Thanks a lot.
  • Daniel Fang said:
    Do you mean you are still not sure it's caused by CCS or compiler version? Is there any early log fix on this before?

    We don't know the cause.  So I cannot say whether this is caused by a known bug.

    Daniel Fang said:
    Why it can be avoided by must add volatile?

    Using volatile disables many optimizations throughout multiple levels of the compiler.  The code generated ends up being very different in many ways.  It is not surprising the volatile avoids the problem, whatever it is.

    Daniel Fang said:
    What's the test case you need? Could you kindly give some more hints on this?

    A test case means I build the same source code the same way you do.  I can't run it.  But I can inspect the assembly code generated by the compiler.  This is often (though not always) good enough to discover the problem.  I list the steps needed to submit a test case in my previous post.  But I can add more detail.  First, preprocess the file.  Follow this link for more details on that process.  You end up with file named something.pp.  Add the file extension .txt to form the file name something.pp.txt.  Attach that file to your next post.  After you click on Reply, click on Use rich formatting in the lower right corner.  This brings up a message compose interface with more features.  Use the paper clip icon to attach the file.  To show the compiler build options, copy-n-paste them from the Console view in CCS.

    Thanks and regards,

    -George

  • 2833x_SysCtrl.pp.txt

    Hi George,

    As attached. Thanks.

  • Thank you for sending in the test case.  I can confirm that the version 4.1.3 compiler generates incorrect code for the function half2quan.  When I build with the version 16.9.2.LTS compiler, the generated code is correct, though I cannot confirm that by running it.

    Unfortunately, the version 4.1.3 compiler is so old, it is impractical for us to support it.  The only way to obtain a fix is by upgrading the compiler.  Please consider downloading the latest version of CCS, which is free. 

    Thanks and regards,

    -George

  • Hi George,

    Thanks for your response.

    Could you send me a email about comparison for generated code by different version compiler? I'd like to make use of it to clear my customer's concern that it's caused by a very old compiler even we don't exactly know what' the cause. Thanks. 

  • Here is the C code for the key function of interest ...

    extern long Position_Numerator1,Position_Divisor1;
    int64 half2quan(int32 target,int64 now, Uint16 Axis)
    {
       int64 all,half;
       int64 TMP;
    
       all = (int64)0x100000000;
       all = (int64)all * Position_Numerator1 / Position_Divisor1;
       half = all;
       half = half >> 1;
       TMP = (int64)target * Position_Numerator1 / Position_Divisor1 - now;
    
       if      (TMP >  half) TMP-=all;
       else if (TMP < -half) TMP+=all;
       return TMP;
    }
    

    I used these build options: -v28 -ml -mt -o3 --symdebug:none -s .

    The option --symdebug:none disables all debug information.  This is a bad idea almost all the time, except for limited cases like this one.  In this case, we are inspecting the code and not running it.  Avoiding the debug information makes it easier to understand the assembly.

    The option -s causes the compiler to add comments to the assembly which make it easier to understand.  There is actually a big difference in these comments, and that's worth comparing.

    These are the comments for version 4.1.3 ...

    ;** 6003	-----------------------    U$9 = (long long)target*(long long)Position_Numerator1/(long long)Position_Divisor1-now;
    ;** 6003	-----------------------    return U$9-9223372036854775808LL;

    It obviously does not compute everything present in the original C source.  Among other things, it never computes the expressions for all or half.  

    These are the comments for version 16.9.2.LTS ...

    ;** 5998	-----------------------    C$17 = (long long)Position_Divisor1;
    ;** 5998	-----------------------    all = ((long long)Position_Numerator1<<32)/C$17;
    ;** 6001	-----------------------    TMP = (long long)target*(long long)Position_Numerator1/C$17-now;
    ;** 6003	-----------------------    C$16 = all>>1;
    ;** 6003	-----------------------    if ( TMP > C$16 ) goto g4;
    ;** 6004	-----------------------    if ( TMP >= -C$16 ) goto g5;
    ;** 6004	-----------------------    TMP += all;
    ;***	-----------------------g4:
    ;** 6003	-----------------------    TMP -= all;
    ;***	-----------------------g5:
    ;** 6005	-----------------------    return TMP;

    Very different.  A much closer match to the original C source.

    Thanks and regards,

    -George