[EXT_EP-11922] Multiplication assignment operation, int32 *= (uint16_t)int16, incorrectly loses the cast to uint16_t during optimization Created: 19/Aug/24 Updated: 15/Oct/25 Resolved: 15/Oct/25 |
|
| 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-12778 |
| Forum URL: | https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/171/t/1401778 |
| Found In Release: | C2000_25.3.0.LTS* C2000_22.6.0.LTS C2000_18.1.7.LTS C2000_21.6.0.LTS C2000_18.12.3.LTS C2000_20.2.0.LTS |
| Fix In Release: | C2000_25.3.0.LTS* C2000_21.6.2.LTS* C2000_22.6.4.LTS* |
| Affected Platform/Device: | default |
| Workaround: | Use --opt_level=off or 0 |
| Description |
|
Multiplication assignment operation like below that assigns to a int32_t/uint32_t variable from either a int16_t variable which is then cast to uint16_t (or an uint16_t variable which is then cast to int16_t) will receive an invalid optimization that incorrectly eliminates the cast: This C code: And this C code: NOTE: below may also have the issue: To see the issue in the generated assembly, use option --src_interlist and below C code: Original description: int16_t gv1_i16 = 0xC0;
int16_t gv2_i16 = 0xC000;
int32_t multiply_with_global()
{
int32_t lv1_i32;
lv1_i32 = gv1_i16;
lv1_i32 *= (uint16_t)gv2_i16;
return lv1_i32; // incorrect: -3145728
}
Build it ... % cl2000 -@options.txt file.c Inspect the resulting assembly file. Ignore the debug directives. The key lines of assembly are: _multiply_with_global:
;* AL assigned to _lv1_i32
;*** 10 ----------------------- _lv1_i32 = gv1_i16;
;*** 11 ----------------------- _lv1_i32 *= gv2_i16;
;*** 12 ----------------------- return _lv1_i32;
MOVW DP,#_gv1_i16 ; [CPU_ARAU]
SETC SXM ; [CPU_ALU]
MOVX TL,@_gv2_i16 ; [CPU_ALU] |11|
MOV ACC,@_gv1_i16 ; [CPU_ALU] |10|
IMPYL ACC,XT,ACC ; [CPU_ALU] |11|
LRETR ; [CPU_FPU]
Note how a signed instruction is used to load gv1_i16. Because of the cast to uint16_t, that should be an unsigned load. |