numerical result changes with optimizer turned on

On my machine (macOS 10.15.5 (19F101)), this simple program changes when the optimizer (-O2) is turned on:

Code Block C
#include <stdio.h>
#include <math.h>
#include "load.h"
int main() {
  float x = load(0x3cc3a2be);
  float result = 100 * powf(2, x);
  printf("result: %f\n", result);
  return 0;
}


Without optimization:

result: 101.669098

With -O2:

result: 101.669106

With load defined in a separate translation unit so this all doesn't get inlined and constant folded:

Code Block
float load(uint32_t value) {
   union {
        float f;
        uint32_t u;
    } f2u;
   f2u.u = value;
   return f2u.f;
}


If you use godbolt.org, you'll see that clang's optimizer replaces powf(2, x) with exp2f which results in very slightly different results (at least on my machine). Here's the generated assembly on my machine:

Code Block
        movl    $1019454142, %edi       ## imm = 0x3CC3A2BE
        callq   _load
        callq   _exp2f


Is this a bug? Does the optimizer claim to produce the same numerical results as non-optimized?
numerical result changes with optimizer turned on
 
 
Q