Uploaded image for project: 'Embedded Software & Tools'
  1. Embedded Software & Tools
  2. EXT_EP-11614

Compiler may ignore necessary truncation of signed integers when used in array access

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Medium Medium
    • Code Generation Tools
    • CODEGEN-11933
    • Hide
      C7000_2.1.1.LTS
      C2000_22.6.1.LTS
      PRU_2.3.3
      MSP430_21.6.1.LTS
      C6000_8.3.12
      C7000_3.1.0.LTS
      C2000_21.6.1.LTS
      MSP430_20.2.7.LTS
      Show
      C7000_2.1.1.LTS C2000_22.6.1.LTS PRU_2.3.3 MSP430_21.6.1.LTS C6000_8.3.12 C7000_3.1.0.LTS C2000_21.6.1.LTS MSP430_20.2.7.LTS
    • Hide
      MSP430_20.2.8.LTS*
      C7000_2.1.3.LTS*
      MSP430_21.6.2.LTS*
      C2000_22.6.2.LTS*
      C6000_8.3.13*
      PRU_2.3.4*
      C2000_21.6.2.LTS*
      C7000_3.1.2.LTS*
      Show
      MSP430_20.2.8.LTS* C7000_2.1.3.LTS* MSP430_21.6.2.LTS* C2000_22.6.2.LTS* C6000_8.3.13* PRU_2.3.4* C2000_21.6.2.LTS* C7000_3.1.2.LTS*
    • default
    • Hide
      Use an optimization level below 2, or replace the cast to short when using s_rot_rad with a call to the _ext intrinsic, for example

      cx_posCoeffs[ul_channelId].s_re = _s_cosTableQ15_c[abs((s32_t)((s16_t)(s_rot_rad))) >> (5u)];

      could be replaced with

      cx_posCoeffs[ul_channelId].s_re = _s_cosTableQ15_c[abs((s32_t)(_ext(s_rot_rad,16,16))) >> (5u)];
      Show
      Use an optimization level below 2, or replace the cast to short when using s_rot_rad with a call to the _ext intrinsic, for example cx_posCoeffs[ul_channelId].s_re = _s_cosTableQ15_c[abs((s32_t)((s16_t)(s_rot_rad))) >> (5u)]; could be replaced with cx_posCoeffs[ul_channelId].s_re = _s_cosTableQ15_c[abs((s32_t)(_ext(s_rot_rad,16,16))) >> (5u)];

      The attached file has these lines ...

            sint16 s_rot_rad = (((sint16)((sint32)(float32)(((float32)(f_rot_rad)*(float32)((32768L)))*(_rcpsp((float32)(float32)((3.1415926535897932f))))))));
            cx_posCoeffs[ul_channelId].s_re = _s_cosTableQ15_c[abs((s32_t)((s16_t)(s_rot_rad))) >> (5u)];
            cx_posCoeffs[ul_channelId].s_im = (_s_cosTableQ15_c[abs((s32_t)((s16_t)((s32_t)(s_rot_rad) - (s32_t)(16384u)))) >> (5u)]);
      

      In the above code cx_posCoeffs[ul_channelId].s_re and cx_posCoeffs[ul_channelId].s_im are fields of a struct, each are signed 16 bit integers.
      _s_cosTableQ14_c is an array containing signed 16 bit integers
      f_rot_rad is a 32 bit floating point number

      In the first array access, the compiler incorrectly optimizes out the conversion of s_rot_rad from from 32 bits to 16 bits. This only occurs inside array accesses, when converting between signed integer types, where the value of the converted integer is truncated.

      Later in execution, these values are printed out ...

         for (ii = 0; ii < ((4) * (4)); ii++) {
            printf(" im = %d, re = %d \n", _cx_posCoeffs1[ii].s_im, _cx_posCoeffs1[ii].s_re);
      

      Build it with no optimization ...

      $ cl6x -@options.txt file.c -z -o no_opt.out -l lnk.cmd
      

      Run it to see this output ...

       im = 512, re = 0 
       im = 384, re = 127 
       im = 256, re = 255 
       im = 128, re = 383 
       im = 1, re = 510 
       im = 126, re = 638 
       im = 254, re = 766 
       im = 381, re = 893 
       im = 509, re = 1021 
       im = 637, re = 898 
       im = 765, re = 770 
       im = 892, re = 643 
       im = 1020, re = 515 
       im = 899, re = 387 
       im = 772, re = 260 
       im = 644, re = 132 
      

      The customer reports this is correct output. Build it with optimization level 3 ...

      cl6x -@options.txt -o3 file.c -z -o with_opt.out -l lnk.cmd
      

      Run it to see different output ...

       im = 512, re = 0 
       im = 384, re = 0 
       im = 256, re = 0 
       im = 128, re = 0 
       im = 1, re = 0 
       im = 126, re = 0 
       im = 254, re = 0 
       im = 381, re = 0 
       im = 509, re = 0 
       im = 637, re = 0 
       im = 765, re = 0 
       im = 892, re = 0 
       im = 1020, re = 0 
       im = 899, re = 0 
       im = 772, re = 0 
       im = 644, re = 0 
      

      Notice the im values are the same, but the re values are different. Both values come from a lookup into the same array, but compute the array index differently. It appears the index for the re lookup is computed incorrectly.

            syncuser TI User
            syncuser TI User
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: