https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79436
Bug ID: 79436 Summary: [ARM Cortex-M4F] VFMA used in place of subtraction gives inexact results Product: gcc Version: 6.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: freddie_chopin at op dot pl Target Milestone: --- Target: arm-none-eabi Created attachment 40699 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40699&action=edit test case In some very specific code paths with specific optimization compiler generates VNEG (negate) + VFMA (multiply and accumulate) instead of VSUB + VMUL. Most likely this is not a problem in most cases, but in the test case I attach this leads to inexact results in a well-defined code. The variable "distance", which is basically a length of a difference of two _IDENTICAL_ vectors multiplied by some constant factor, is expected to be 0. "x - x" for components of each vector gives zero. "0 * 0" gives zero. "0 + 0" gives zero. "sqrtf(0)" gives zero. "0 * x" gives 0. These are basically all the operations in the example. However the value of "distance" is calculated to be 1.34925369e-06 and the assertion fails. Several notes: 1. The code seems complicated, but if I simplify it, different sequence of instructions is generated, and the VNEG + VFMA used instead of VSUB + VMUL is essential to the problem. To generate slightly different sequence it's enough to uncomment the assertion that checks equality of vectors. 2. The problem appears on -O2, -O3 and -Os. It does not appear on -O1 and -Og (probably neither with -O0, but I did not check). 3. The problem can be observed for GCC 6.3.0 and GCC 5.3.1. With or without ARM patches. Exact compilation command: arm-none-eabi-g++ -Wall -Wextra -Wshadow -std=gnu++11 -g -ggdb3 -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -c vfma.cpp -o vfma.o I also attach assembly output of the "invalid" version (-O2) and "valid" version (-O1).