-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Medium
-
Code Generation Tools
-
CODEGEN-12500
-
-
-
default
-
Use --opt_level=1 or lower or use signed integer instead of unsigned
For expressions that mix variables of type float with loop-index variables
of type unsigned int (or eabi with doubles and unsigned int/long) the
optimizer is incorrectly breaking up the integer expression and distributing
the float variable into the integer expression that uses the loop-index
variable.
This C code:
typedef unsigned int uint16_t;
struct TEST_STRUCT
{
float f1;
float f2;
};
volatile struct TEST_STRUCT TEST[5];
void TEST_FCN(float w)
{
uint16_t Index;
float w_temp;
for(Index = 5 ; Index > 0 ; Index--)
{
w_temp = w * (Index * 2 - 1);
TEST[Index - 1].f1 = w_temp;
}
}
Incorrectly optimizes to below using options:
cl2000 test.c -o2 -s --float_support=fpu32
Inspect the resulting assembly code. Find the compiler generated comments that
show how the loop is optimized.
||TEST_FCN||:
;*** ----------------------- U$15 = &((volatile float *)TEST)[8];
;*** ----------------------- U$7 = 9.0F;
;*** ----------------------- L$1 = 4;
;*** -----------------------g2:
;*** 21 ----------------------- *U$15 = U$7*w;
;*** 18 ----------------------- U$15 -= 2;
;*** 18 ----------------------- U$7 += 65534.0F; <---- Incorrect. Should be: -=2.0f
;*** 18 ----------------------- if ( (--L$1) != (-1) ) goto g2;
;*** ----------------------- return;
MOVB XAR6,#4 ; [CPU_ALU]
MOVL XAR4,#||TEST||+16 ; [CPU_ARAU]
MOVIZ R3H,#16656 ; [CPU_FPU]
RPTB ||$C$L2||,AR6 ; [CPU_ALU] |18|
||$C$L1||:
MOVIZ R2H,#18303 ; [CPU_FPU] |18|
MPYF32 R1H,R0H,R3H ; [CPU_FPU] |21|
MOVXI R2H,#65024 ; [CPU_FPU] |18|
ADDF32 R3H,R3H,R2H ; [CPU_FPU] |18|
|| MOV32 *+XAR4[0],R1H ; [CPU_FPU] |21|
SUBB XAR4,#4 ; [CPU_ALU] |18|
||$C$L2||:
LRETR ; [CPU_ALU]