-
Bug
-
Resolution: Fixed
-
Medium
-
Code Generation Tools
-
CODEGEN-11933
-
-
-
default
-
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.