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.

Unexpected abs function behavior (IMHO critical bug)

Other Parts Discussed in Thread: HALCOGEN

Crosspost from compiler forum

Hi!

Embedded abs function have unexpected behavior. When I call abs(some_big_int64-other_big_int64) I expect

1) Calculate difference

2) Strip int64 value to int

3) return abs value

But result is very strange. Abs function return NEGATIVE value! I thest this code on TMS570LS0914 using arm_15.12.3.LTS

static int abs_ (int x) {
    if (x < 0) {
        return -x;
    }
    return x;
}

int main() {
        int64_t v1, v2, v3, v4, v5, v6, v7;
        v1 = 0x7FFFFFFFUL;
        v2 = v1 + 1;
        v3 = abs (v2 - v1); //!!!!! v3=-1
        v4 = v2 - v1;
        v5 = abs (v4);
        v6 = abs_ (v2 - v1);
        v7 = abs_ (v4);
        LOG_WARNING (SYS, "v1=%" PRId64 " 0x%" PRIX64, v1, v1); //v1=2147483647 0x7FFFFFFF
        LOG_WARNING (SYS, "v2=%" PRId64 " 0x%" PRIX64, v2, v2); //v2=2147483648 0x80000000
        LOG_WARNING (SYS, "v3=%" PRId64 " 0x%" PRIX64, v3, v3); //v3=-1 0xFFFFFFFFFFFFFFFF
        LOG_WARNING (SYS, "v4=%" PRId64 " 0x%" PRIX64, v4, v4); //v4=1 0x1
        LOG_WARNING (SYS, "v5=%" PRId64 " 0x%" PRIX64, v5, v5); //v5=1 0x1
        LOG_WARNING (SYS, "v6=%" PRId64 " 0x%" PRIX64, v6, v6); //v6=1 0x1
        LOG_WARNING (SYS, "v7=%" PRId64 " 0x%" PRIX64, v7, v7); //v7=1 0x1
}

  • Hi Vladimir,

     I will forward your post to the compiler team. I see the same.

  • I'm sorry, I cannot reproduce this error. What are your exact command line options? Please cut-and-paste them from the build console window.
  • "C:/ti/ccsv6/tools/compiler/arm_15.12.3.LTS/bin/armcl" -mv7R4 --code_state=32 --float_support=VFPv3D16 --opt_for_speed=0 --include_path="C:/ti/ccsv6/tools/compiler/arm_15.12.3.LTS/include" --include_path="C:/auto/platform_tx/platform/toolbox" --include_path="C:/auto/common/matlab_R2015a/include" --include_path="C:/auto/simulink/generated/dcu_model_p2/slprj/ert/_sharedutils" --include_path="C:/auto/platform_tx/platform/src" --include_path="C:/auto/platform_tx/platform/src_io" --include_path="C:/auto/platform_tx/tx_dcu/generated" --include_path="C:/auto/simulink/functions" --include_path="C:/auto/common/utils" --include_path="C:/auto/common/utils_tms" --include_path="C:/auto/common/utils_bootloader" --include_path="C:/auto/common/FlashApi/include" --include_path="C:/auto/platform_tx/platform/halcogen_no_os/include" --include_path="C:/auto/platform_tx/tx_dcu/src" --include_path="C:/auto/simulink/generated/dcu_model_p2/dcu_model_p2_ert_rtw" --include_path="C:/auto/simulink/generated/dcu_model_p2/dcu_model_p2_ert_rtw/referenced_model_includes" --include_path="C:/auto/simulink/generated/dcu_model_p2/slprj/ert/dcu_func_model_v1" --include_path="C:/auto/simulink/generated/dcu_model_p2/slprj/ert/Priority_Managment" --include_path="C:/auto/simulink/generated/dcu_model_p2/slprj/ert/SEVCON_Processing" --check_misra="1,2,4,5.3,6.2,6.5,8.2,8.5,8.6,8.7,9" -g --strict_ansi --define=FOR_BOOTLOADER --define=false=0 --define=true=1 --define=SIMULINK --define=NO_OS --emit_warnings_as_errors --diag_wrap=off --diag_warning=225 --display_error_number --abi=eabi --enum_type=packed --preproc_with_compile --preproc_dependency="src/main.d" --obj_directory="src" "../src/main.c"
  • I have reproduced the problem and have filed CODEGEN-1555 to track this issue.
  • Vladimir Romanov said:
    But result is very strange. Abs function return NEGATIVEvalue!

    The variables are of type int64_t, which is long long for the ARM compiler.

    The abs function operates on type int (32 bits for the ARM compiler).

    Given that the variables are long long try using llabs instead of abs, where llabs operates on type long long.

  • Compiler must
    1) calculate difference using 64-bit values (get int64 result with value 1)
    2) convert int64 to int32 (get int32 result with value 1)
    3) convert to positive value (1)
    4) convert int32 result to 64 bit variable


    In my code difference is usually very small and fit into 32 bit. Now I convert code to use custom macros.