Problematic code:
float lower16BitAsFloat_incorrect(uint32_t a)
{
const uint32_t lo16 = a & 0x0000FFFFU;
return _itof(lo16);
}
float lower16BitAsFloat_correct(uint32_t a)
{
return _itof(a & 0x0000FFFFU);
}
We expect both functions to producce functionally identical target code.
Calling the compiler with the following flags: -mv6600 --c++14 -O3 -DNDEBUG --auto_inline=0 -ms1
produces wrong output for the first function. Note the missing EXTU instruction in lower16BitAsFloat_incorrect:
lower16BitAsFloat_incorrect(unsigned int):
RETNOP B3,5 ; [] |14|
lower16BitAsFloat_correct(unsigned int):
RETNOP B3,4 ; [] |26|
EXTU .S1 A4,16,16,A4 ; [A_S66] |25|
Trying to narrow down the triggering condition, we found that the following code produces correct binaries.
So, we suspect, that the issue is related / limited to 16-bit handling and is not triggered because of a FP subnormal pattern.
float lower17BitAsFloat_correct(uint32_t a)
{
const uint32_t lo17 = a & 0x0001FFFFU;
return _itof(lo17);
}
float lower15BitAsFloat_correct(uint32_t a)
{
const uint32_t lo15 = a & 0x00007FFFU;
return _itof(lo15);
}
Produces:
lower17BitAsFloat_correct(unsigned int):
RETNOP B3,4 ; [] |8|
EXTU .S1 A4,15,15,A4 ; [A_S66] |7|
lower15BitAsFloat_correct(unsigned int):
RETNOP B3,4 ; [] |20|
EXTU .S1 A4,17,17,A4 ; [A_S66] |19|