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.

Erraneous code generated without warning for __tbit in logic expression

Bug report for TMS320C2000 C/C++ Compiler v6.1.2, also seen in v6.0.5 and v5.2.13.

Description:

The if-statement in the code example 1 below will ignore the second term (!(bar != 0)) at optimization levels -O0 and above. The optimization rewrites the code to the statement shown in the function code example 2, which produces similarly erroneous code when compiled without any optimization.

This can be seen from the assembly code produced by the compiler, show below the code.

A code example 3 is also included which will cause an INTERNAL ERROR to be issued from the compiler, and is probably related to this bug. This is, however, a much less serious bug, as the one documented above creates an erroneous running program with no warning.

Workaround:

Use e.g. (foo & 1) instead of __tbit(foo, 0). Only use __tbit in standalone expressions.

Code example 1:

int
tbitbug_opt_lvl0(int foo, int bar)
{
  if (!__tbit(foo, 0) && !(bar != 0))
    return 1;
  else
    return 0;
}

Relevant assembler output using cl2000 -s -O0:

Notice that AH (the bar argument) is simply overwritten by 0.

_tbitbug_opt_lvl0:
;*** 25 ----------------------- return (__tbit(foo, 0)|bar) == 0;
MOVB AH,#0 ; [CPU_] |25|
TBIT AL,#0 ; [CPU_] |25|
B $C$L1,TC ; [CPU_] |25|
; branchcc occurs ; [] |25|
MOVB AH,#1 ; [CPU_] |25|
$C$L1:
MOV AL,AH ; [CPU_] |25|
RET ; [CPU_]
; return occurs ; []

Code example 2

int
tbitbug_no_opt(int foo, int bar)
{
  return (__tbit(foo, 0)|bar) == 0;
}

Relevant assembly code produced by compiling with -s

Notice that AH (the bar argument) is copied to *-SP[2], but never used.

_tbitbug_no_opt:
ADDB SP,#2 ; [CPU_U]
MOV *-SP[1],AL ; [CPU_] |30|
;----------------------------------------------------------------------
; 31 | return (__tbit(foo, 0)|bar) == 0;
;----------------------------------------------------------------------
MOVB AL,#0 ; [CPU_] |31|
TBIT *-SP[1],#0 ; [CPU_] |31|
MOV *-SP[2],AH ; [CPU_] |30|
B $C$L3,TC ; [CPU_] |31|
; branchcc occurs ; [] |31|
MOVB AL,#1 ; [CPU_] |31|
$C$L3:
SUBB SP,#2 ; [CPU_U]
RET ; [CPU_]
; return occurs ; []

Code example 3

Causes an INTERNAL ERROR: Illegal use of intrinsic: __tbit

int
tbit_test(int foo, int bar)
{
return __tbit(foo, 0)|bar;
}


BR

Tore

  • Thank you for taking the time to submit a test case.  I can reproduce your results.  I filed SDSCM00047076 in the SDOWP system to have this issue addressed.  Feel free to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George