Tool/software:
Hello,
I encountered some unexpected behavior in one of our products and was able to track the behavior down to an apparent compiler bug. After some trial and error, I was able to work the code into a minimal test case, and I created a CCS project to demonstrate the bug. First, the compiler information:
- Compiler version: 8.3.13 (latest)
- Compiler options used: -mv6600 -O2 --include_path="C:/test/CompilerBugTest" --include_path="C:/test/ti-cgt-c6000_8.3.13/include" --preproc_with_comment --preproc_with_compile --diag_warning=225 --diag_wrap=off --display_error_number -k
The bug occurs when bugFunction() is compiled at optimization level 2 or higher. The assembler output shows a certain EXTU operation that does not make sense and ends up causing the bad behavior:
_Z11bugFunctionv:
...
MVKL .S2 testValues,B4 ; [B_Sb66] |15|
MVKH .S2 testValues,B4 ; [B_Sb66] |15|
LDDW .D2T2 *B4(0),B1:B0 ; [B_D64P] |15|
NOP 4 ; [A_L66]
EXTU .S2 B0,24,24,B0 ; [B_Sb66] |19|
|| [!B1] MVKL .S1 outputStruct,A4 ; [A_S66] |21|
|| [!B1] MVK .L1 1,A3 ; [A_L66] |21|
...
The EXTU instruction zeroes out the upper 24 bits of B0, which is the register that contains the value testValues[0]. As a result, bugFunction() computes that both testValues[0] and testValues[1] are zero even when the upper 24 bits of testValues[0] are not zero.
The output of the test program is correct when bugFunction() is compiled at optimization level 1 or lower. The correct output is as follows:
testValuesAreBothZero: testValues[0] = 0x00000000, testValues[1] = 0x00000000
The incorrect output of the program occurs when bugFunction() is compiled at optimization level 2 or higher (only the final line of the output is actually correct):
testValuesAreBothZero: testValues[0] = 0x00000100, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00000200, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00000400, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00000800, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00001000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00002000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00004000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00008000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00010000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00020000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00040000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00080000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00100000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00200000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00400000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00800000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x01000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x02000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x04000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x08000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x10000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x20000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x40000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x80000000, testValues[1] = 0x00000000
testValuesAreBothZero: testValues[0] = 0x00000000, testValues[1] = 0x00000000