This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/79436] New: [ARM Cortex-M4F] VFMA used in place of subtraction gives inexact results


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).

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]