This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/ARM-CGT: Signed single-precision floating-point zero has sign bit unset

Part Number: ARM-CGT


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