[EXT_EP-11614] Compiler may ignore necessary truncation of signed integers when used in array access Created: 21/Dec/23  Updated: 22/Feb/24  Resolved: 22/Feb/24

Status: Fixed
Project: Embedded Software & Tools
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Medium
Reporter: TI User Assignee: TI User
Resolution: Fixed Votes: 0
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Product: Code Generation Tools
Internal ID: CODEGEN-11933
Forum URL: https://e2e.ti.com/support/sensors-group/sensors---internal/f/1047/t/1306015
Found In Release: 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
Fix In Release: 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*
Affected Platform/Device: default
Workaround: 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)];

 Description   

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.


Generated at Wed Apr 09 05:00:28 CDT 2025 using Jira 9.12.17#9120017-sha1:aba4002bcd633f188b6a4bb5dd8a0e1f20b79ee4.