⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 285788 in webkit


Ignore:
Timestamp:
Nov 14, 2021, 12:45:44 AM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Prevent fused multiply add during ParseInt
https://bugs.webkit.org/show_bug.cgi?id=232951

Patch by Mikhail R. Gadelha <Mikhail R. Gadelha> on 2021-11-14
Reviewed by Yusuke Suzuki.

When parsing the string in parseInt, gcc can wrongfully generate
a fused multiply-add instruction, causing the conversion to be wrong
for some high values. An add followed by a multiply gives the correct
result and it is the code generated most of the times.

This patch adds a volatile qualifier to the number variable, so the
compiler doesn't try to optimize it, and enables a failing test on
mips.

Alternative solutions that I tried but gcc seems to ignore: #pragma
STDC FP_CONTRACT OFF, compiling with -ffp-contract=off, and setting function
attributes attribute((optimize("fp-contract=off"))) and
attribute((optimize("-ffp-contract=off"))), so volative seems to be
a good compromise.

The issue was found when cross compiling to mips with gcc 8.4.0 and
options -ffp-contract=off -mmadd4.

JSTests:

  • ChakraCore.yaml:

Source/JavaScriptCore:

  • runtime/ParseInt.h:

(JSC::parseInt):

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChakraCore.yaml

    r285263 r285788  
    697697- path: ChakraCore/test/GlobalFunctions/ParseInt1.js
    698698  # Currently fails on the Loongson 3A4000 (in 32-bits mode).
    699   cmd: |
    700     if $architecture == "mips"
    701       skip
    702     else
    703       runChakra :baseline, "NoException", "ParseInt1.baseline", []
    704     end
     699  cmd: runChakra :baseline, "NoException", "ParseInt1.baseline", []
    705700- path: ChakraCore/test/GlobalFunctions/toString.js
    706701  cmd: runChakra :baseline, "NoException", "toString.baseline", []
  • trunk/JSTests/ChangeLog

    r285760 r285788  
     12021-11-14  Mikhail R. Gadelha  <mikhail@igalia.com>
     2
     3        Prevent fused multiply add during ParseInt
     4        https://bugs.webkit.org/show_bug.cgi?id=232951
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        When parsing the string in parseInt, gcc can wrongfully generate
     9        a fused multiply-add instruction, causing the conversion to be wrong
     10        for some high values. An add followed by a multiply gives the correct
     11        result and it is the code generated most of the times.
     12
     13        This patch adds a volatile qualifier to the number variable, so the
     14        compiler doesn't try to optimize it, and enables a failing test on
     15        mips.
     16
     17        Alternative solutions that I tried but gcc seems to ignore: #pragma
     18        STDC FP_CONTRACT OFF, compiling with -ffp-contract=off, and setting function
     19        attributes __attribute__((optimize("fp-contract=off"))) and
     20        __attribute__((optimize("-ffp-contract=off"))), so volative seems to be
     21        a good compromise.
     22
     23        The issue was found when cross compiling to mips with gcc 8.4.0 and
     24        options -ffp-contract=off -mmadd4.
     25
     26        * ChakraCore.yaml:
     27
    1282021-11-12  Joseph Griego  <jgriego@igalia.com>
    229
  • trunk/Source/JavaScriptCore/ChangeLog

    r285770 r285788  
     12021-11-14  Mikhail R. Gadelha  <mikhail@igalia.com>
     2
     3        Prevent fused multiply add during ParseInt
     4        https://bugs.webkit.org/show_bug.cgi?id=232951
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        When parsing the string in parseInt, gcc can wrongfully generate
     9        a fused multiply-add instruction, causing the conversion to be wrong
     10        for some high values. An add followed by a multiply gives the correct
     11        result and it is the code generated most of the times.
     12
     13        This patch adds a volatile qualifier to the number variable, so the
     14        compiler doesn't try to optimize it, and enables a failing test on
     15        mips.
     16
     17        Alternative solutions that I tried but gcc seems to ignore: #pragma
     18        STDC FP_CONTRACT OFF, compiling with -ffp-contract=off, and setting function
     19        attributes __attribute__((optimize("fp-contract=off"))) and
     20        __attribute__((optimize("-ffp-contract=off"))), so volative seems to be
     21        a good compromise.
     22
     23        The issue was found when cross compiling to mips with gcc 8.4.0 and
     24        options -ffp-contract=off -mmadd4.
     25
     26        * runtime/ParseInt.h:
     27        (JSC::parseInt):
     28
    1292021-11-12  Darin Adler  <darin@apple.com>
    230
  • trunk/Source/JavaScriptCore/runtime/ParseInt.h

    r284187 r285788  
    163163    int firstDigitPosition = p;
    164164    bool sawDigit = false;
     165#if COMPILER(GCC)
     166    // Due to a bug found in GCC v8.4.0, a wrong fused multiply-add optimization can be inserted when calculating the final number,
     167    // in number *= radix; number += digit;, so add volatile to prevent optimizations.
     168    // GCC v8.4.0 also seems to ignore #pragma STDC FP_CONTRACT OFF, compiling with -ffp-contract=off, and setting function attributes
     169    // __attribute__((optimize("fp-contract=off"))) and __attribute__((optimize("-ffp-contract=off"))).
     170    volatile double number = 0;
     171#else
    165172    double number = 0;
     173#endif
    166174    while (p < length) {
    167175        int digit = parseDigit(data[p], radix);
Note: See TracChangeset for help on using the changeset viewer.