IEEE 754 standard and C language float data type
That is implementation-defined.

A compiler may compile a program using float and double types so that it follows the behaviour specified in IEEE 754, it may deviate from that standard or do something entirely different.

Which it is should be documented in the compiler manual. Several compilers have different modes, and can favour adherence to the standard over speed, speed over compliance, or try to find a sensible middle ground.

For example, the FPU in the x86 architecture is close to the standard, but has a number of key differences, for example the internal data format is 80 bits wide, so in order to make this FPU behave standards-compliant, you need to round every intermediate result to 32 or 64 bits.

Obviously, that is slow and will provide less precision than not rounding, so the default behaviour of most compilers is to leave intermediate results on the FPU stack. This is usually what you want, but if you are auditing your program, the compiler or the hardware implementation, that deviation will cause a deviation from the expected value.

In this case, use /fp:precise (MSVC), or -fno-fast-math (GCC, clang) to force strict compliance. The program will be slower, but the results are bit-exact what you would expect.

On platforms where the FPU is not even close to the IEEE standard, asking for precise math will most likely rewrite the floating-point code to integer operations applied to members of a packed data structure -- a significant performance hit.

Other compilers may not offer a strict compliance mode, and several high-performance computing architectures have a fully conforming hardware implementation so no workarounds are required.

Full IEEE compliance also limits the optimizations that may be performed, as reordering operations may alter results as well, by avoiding or causing over- or underflows, so even on fully conforming hardware architectures, there is still potential for a compiler to be non-conforming.