[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. 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. |