Tool/software:
Compiler version:TI v22.6.1.LTS
When I was writing an algorithm, I found that after turning on the O2 level optimization of the compiler, the coefficient generation of the controller was incorrect. So I wrote the following code to test, in which I gave 1 to the input parameter w:
struct TEST_STRUCT
{
float f1;
float f2;
};
volatile struct TEST_STRUCT TEST[5];
void TEST_FCN(float w)
{
Uint16 Index;
float w_temp;
for( Index = 5 ; Index > 0 ; Index-- )
{
w_temp = w * ( Index * 2 - 1 );
TEST[Index - 1].f1 = w_temp;
}
}
The assembly code generated after turning on O2 is as follows:
MOVB XAR6,#4 ; [CPU_ALU]
MOVL XAR4,#||TEST||+16 ; [CPU_ARAU]
MOVIZ R3H,#16656 ; [CPU_FPU]
.dwpsn file "../main.c",line 22,column 22,is_stmt,isa 0
RPTB ||$C$L2||,AR6 ; [CPU_ALU] |22|
; repeat block starts ; []
||$C$L1||:
MOVIZ R2H,#18303 ; [CPU_FPU] |22|
.dwpsn file "../main.c",line 25,column 9,is_stmt,isa 0
MPYF32 R1H,R0H,R3H ; [CPU_FPU] |25|
.dwpsn file "../main.c",line 22,column 22,is_stmt,isa 0
MOVXI R2H,#65024 ; [CPU_FPU] |22|
ADDF32 R3H,R3H,R2H ; [CPU_FPU] |22|
|| MOV32 *+XAR4[0],R1H ; [CPU_FPU] |25|
SUBB XAR4,#4 ; [CPU_ALU] |22|
; repeat block ends ; []
||$C$L2||:
$C$DW$11 .dwtag DW_TAG_TI_branch
.dwattr $C$DW$11, DW_AT_low_pc(0x00)
.dwattr $C$DW$11, DW_AT_TI_return
LRETR ; [CPU_ALU]
; return occurs ; []
The problem lies in the optimization of (Index * 2 - 1): the compiler fixes (Index * 2 - 1) to the R3H register, so that R3H is subtracted by 2 for each cycle. Since Index is declared as Uint16 unsigned integer type, the compiler assigns R2H a value of 0x477ffe00 (65534) and wants to perform equivalent subtraction through R3H=R2H+R3H. However, RxH is a floating-point register, and the compiler can only call ADDF32 to perform floating-point addition, resulting in incorrect results:

If I declare Index as int16, the compiled assembly code is correct and the result is correct:

MOVB XAR6,#4 ; [CPU_ALU]
MOVL XAR4,#||TEST||+16 ; [CPU_ARAU]
MOVIZ R1H,#16656 ; [CPU_FPU]
.dwpsn file "../main.c",line 21,column 22,is_stmt,isa 0
RPTB ||$C$L2||,AR6 ; [CPU_ALU] |21|
; repeat block starts ; []
||$C$L1||:
.dwpsn file "../main.c",line 24,column 9,is_stmt,isa 0
MPYF32 R2H,R0H,R1H ; [CPU_FPU] |24|
.dwpsn file "../main.c",line 21,column 22,is_stmt,isa 0
ADDF32 R1H,R1H,#49152 ; [CPU_FPU] |21|
.dwpsn file "../main.c",line 24,column 9,is_stmt,isa 0
MOV32 *+XAR4[0],R2H ; [CPU_FPU] |24|
.dwpsn file "../main.c",line 21,column 22,is_stmt,isa 0
SUBB XAR4,#4 ; [CPU_ALU] |21|
NOP ; [CPU_ALU]
NOP ; [CPU_ALU]
; repeat block ends ; []
||$C$L2||:
$C$DW$11 .dwtag DW_TAG_TI_branch
.dwattr $C$DW$11, DW_AT_low_pc(0x00)
.dwattr $C$DW$11, DW_AT_TI_return
LRETR ; [CPU_ALU]
; return occurs ; []
It can be seen that at this time (Index * 2 - 1) is fixed as R1H, and the generated assembly instruction is ADDF32 R1H, R1H, #49152, that is, R1H=R1H-2.
Is this a BUG?
Thank you.

