Tool/software: TI C/C++ Compiler
Hi,
We're encountering what appears to be a code generation bug in ARM-CGT 18.12.2.
We have some code that uses the literal -0.0F and expects the sign bit to be set; unfortunately, this does not seem to be the case. Generating a signed zero using std::copysign works fine, however. Additionally, when inspecting the object representation, it does indeed look like the sign bit is not set:
#include <cmath>
#include <cassert>
#include <cstring>
#include <cstdio>
#include <cstdint>
template <typename T, typename U>
T byte_cast(const U& value)
{
T result;
std::memcpy(static_cast<void*>(&result), static_cast<const void*>(&value), sizeof(T));
return result;
}
int main()
{
const float a = 0.0f;
const float b = -0.0f;
const float c = std::copysign(0.0f, -1.0f);
std::printf("%08x\n", byte_cast<uint32_t>(a)); // expected: 0x00000000, actual: 0x00000000
std::printf("%08x\n", byte_cast<uint32_t>(b)); // expected: 0x80000000, actual: 0x00000000
std::printf("%08x\n", byte_cast<uint32_t>(c)); // expected: 0x80000000, actual: 0x80000000
assert(std::signbit(a) == false); // ok
assert(std::signbit(b) == true); // fails!
assert(std::signbit(c) == true); // ok
}
In this snippet, I would expect all three assertions to pass. Note that the equivalent double-precision code works fine.
Is this a known issue in the compiler, and is there a workaround that doesn't involve explicitly calling std::copysign?
Our target platform is a TDA3 SOC, and we're using the following compiler flags:
-qq -mv7M4 --float_support=vfplib --endian=little --relaxed_ansi --define=SOC_TDA3XX --keep_unneeded_statics --diag_wrap=off --display_error_number --diag_suppress=556 --wchar_t=16 --fp_reassoc=off --float_operations_allowed=all --ramfunc=off --abi=eabi -O3 --opt_for_speed=4 --c++14
And the following linker flags:
-w -q -x --rom_model --zero_init=on --cinit_compression=off --absolute_exe