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.

C6000-CGT: Loop optimization bug on 8.3.10

Part Number: C6000-CGT

Hello,

Below is a minimal example of a bug where a variable is set through a reference and then used in a function call. The set value is not used, rather the initial value is observed in the called function. In the call to 

getResultCode(float, int32_t) the input quality should be 1.0F. However the if-case returning 0U is not triggered. Instead 1U is returned in the -O3 build.

With the below code, the bug is not observed if we use a `for (int i = 0; i < 2; ++i)` loop, however changing to this loop in the original code still results in incorrect compiled code. Adjusting the size of `
uint8_t otherData[128];` seems to impact the reproducibility of the bug.



Compiler version

cl6x --help
TMS320C6x C/C++ Compiler                v8.3.10
Tools Copyright (c) 1996-2018 Texas Instruments Incorporated


Compilation flags. The bug is observed at -O2 and -O3.

-qq -mv6600 --relaxed_ansi --define=SOC_TDA3XX --keep_unneeded_statics --diag_wrap=off --display_error_number --diag_suppress=556 --diag_suppress=2458 --mem_model:data=far --wchar_t=16 --fp_reassoc=off --float_operations_allowed=all --ramfunc=off --emit_warnings_as_errors -O3 --opt_for_speed=4 -DNDEBUG --symdebug:none --c++14


Header

#ifndef COMPILER_BUG_HPP_
#define COMPILER_BUG_HPP_

#include <cstdint>

struct QualityAndStatus
{
  float quality;
  uint8_t status;
};

struct Results
{
  uint8_t otherData[128];

  QualityAndStatus qualityAndStatus[2];
};

void getResults(Results& outResults);

#endif  // COMPILER_BUG_HPP_


Source

#include "compiler_bug.hpp"

#include <initializer_list>

namespace
{
uint8_t getResultCode(int32_t const inStatusIdx)
{
  constexpr uint8_t STATUS_MAPPINGS[2]{0U, 1U};
  return STATUS_MAPPINGS[inStatusIdx];
}

uint8_t getResultCode(float const inQuality, int32_t const inStatusIdx)
{
  if (inQuality > 0.0F)
  {
    return 0U;
  }

  uint8_t code = getResultCode(inStatusIdx);

  if (code == 0U)
  {
    code = 1U;
  }

  return code;
}
}  // namespace

void getResults(Results& outResults)
{
  for (auto const idx : {0, 1})
  {
    QualityAndStatus& qualityAndStatus = outResults.qualityAndStatus[idx];

    qualityAndStatus.quality = 1.0F;
    qualityAndStatus.status = getResultCode(qualityAndStatus.quality, 0);
  }
}


Test app

#include "compiler_bug.hpp"

#include <xdc/runtime/System.h>

void init()
{
  Results results{};
  getResults(results);

  // Prints 0 with -O1 and 1 with -O2.
  System_printf("Result 1: %d\n", results.qualityAndStatus[0].status);
  System_printf("Result 2: %d\n", results.qualityAndStatus[1].status);
}