This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARMCLANG V6.12 BUG or my fault?

Hello,

My function calculates scalar value from dB value using formular
scalar = 10 ^ (dB / 20)

In case of ARMCLANG V6.12 and Optimizer Level -O2 the calculation fails as
it is shown in my test code.

Maybe, I overlook something, do I?

#include "stm32f4xx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>

static volatile int8_t dB;
static int8_t lastGain;

/**/
void setGain(int8_t gain)
{
  float vol;

  if (lastGain == gain) {
    // value is already set
    return;
  }
  // calculate scalar value
  vol = powf(10.f, (float)gain / 20.f);  // = 0.199526...
  // check limits
  if (vol > 10) {
    // "vol out of range" is printed in case of ARMCLANG V6.12 and Optimization > -O2
    printf("vol out of range\n");
  } else {
    // "passed" is printed in case of ARMCLANG V6.12 and Optimization -O0 or -O1
    printf("passed\n");
    lastGain = gain;
  }
}

/**/
int main(void)
{
  dB = -14;
  for(;;) {
    setGain(dB);
  }
}

Parents
  • I have quickly looked into this and I can replicate the behavior (either on target or simulator).

    It looks like the compiler optimization incorrectly converts "(float)gain" into 242.0f instead of -14.0f.

    "gain" value is 0xFFFFFFF2 (-14) on function setGain entry which is correct. However due to the comparison with lastGain the value gets truncated to 0x000000F2 and then later reused to convert to float which results in incorrect value 242.0f.

    I have created a support ticket for this problem.

Reply
  • I have quickly looked into this and I can replicate the behavior (either on target or simulator).

    It looks like the compiler optimization incorrectly converts "(float)gain" into 242.0f instead of -14.0f.

    "gain" value is 0xFFFFFFF2 (-14) on function setGain entry which is correct. However due to the comparison with lastGain the value gets truncated to 0x000000F2 and then later reused to convert to float which results in incorrect value 242.0f.

    I have created a support ticket for this problem.

Children
  • "gain" value is 0xFFFFFFF2 (-14) on function setGain entry which is correct.

    Actually, if that were the case, it would not be correct. The value of "gain" cannot be that --- because that value is way too large to fit into the int8_t type.

    Now, the CPU register holding the value may contain all those bytes, but only one of those can be "gain" itself.

    The actual problem then would be a failure to sign-extend this single byte before passing it to a compiler intrinsic function that expects to be fed a 32-bit value.