Bug 232951

Summary: Prevent fused multiply add during ParseInt
Product: WebKit Reporter: Mikhail R. Gadelha <mikhail>
Component: New BugsAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: ews-watchlist, keith_miller, mark.lam, msaboff, saam, tzagallo, webkit-bug-importer, ysuzuki
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch none

Mikhail R. Gadelha
Reported 2021-11-10 10:12:36 PST
Prevent fused multiply add during ParseInt
Attachments
Patch (4.07 KB, patch)
2021-11-10 10:23 PST, Mikhail R. Gadelha
no flags
Patch (4.07 KB, patch)
2021-11-10 10:25 PST, Mikhail R. Gadelha
no flags
Patch (4.09 KB, patch)
2021-11-10 11:31 PST, Mikhail R. Gadelha
no flags
Patch (4.87 KB, patch)
2021-11-12 05:36 PST, Mikhail R. Gadelha
no flags
Patch (4.83 KB, patch)
2021-11-13 05:28 PST, Mikhail R. Gadelha
no flags
Mikhail R. Gadelha
Comment 1 2021-11-10 10:23:58 PST
Mikhail R. Gadelha
Comment 2 2021-11-10 10:25:44 PST
Yusuke Suzuki
Comment 3 2021-11-10 10:51:29 PST
Comment on attachment 443833 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=443833&action=review Commented. > Source/JavaScriptCore/ChangeLog:18 > + When parsing the string in parseInt, a compiler 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. > + > + The issue was found when cross compiling to mips with gcc 8.4.0 and > + options -ffp-contract=off -mmadd4. This is GCC issue, and we should not use `volatile` here. We should disable GCC's this optimization for this function via pragma etc. https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Specific-Option-Pragmas.html#Function-Specific-Option-Pragmas https://stackoverflow.com/questions/34436233/fused-multiply-add-and-default-rounding-modes
Mikhail R. Gadelha
Comment 4 2021-11-10 11:07:18 PST
(In reply to Yusuke Suzuki from comment #3) > Comment on attachment 443833 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=443833&action=review > > Commented. > > > Source/JavaScriptCore/ChangeLog:18 > > + When parsing the string in parseInt, a compiler 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. > > + > > + The issue was found when cross compiling to mips with gcc 8.4.0 and > > + options -ffp-contract=off -mmadd4. > > This is GCC issue, and we should not use `volatile` here. We should disable > GCC's this optimization for this function via pragma etc. > https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Specific-Option- > Pragmas.html#Function-Specific-Option-Pragmas > https://stackoverflow.com/questions/34436233/fused-multiply-add-and-default- > rounding-modes But these pragmas disable optimization for the whole function. Are you sure we should disable optimization for the whole function? I also tried to use `#pragma STDC FP_CONTRACT` but gcc doesn't seem to accept it yet: https://stackoverflow.com/questions/43352510/difference-in-gcc-ffp-contract-options On other platforms that I tested, the compilers already generate an unfused multiply-add, so we don't seem to be generating worse code either.
Yusuke Suzuki
Comment 5 2021-11-10 11:16:43 PST
(In reply to Mikhail R. Gadelha from comment #4) > (In reply to Yusuke Suzuki from comment #3) > > Comment on attachment 443833 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=443833&action=review > > > > Commented. > > > > > Source/JavaScriptCore/ChangeLog:18 > > > + When parsing the string in parseInt, a compiler 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. > > > + > > > + The issue was found when cross compiling to mips with gcc 8.4.0 and > > > + options -ffp-contract=off -mmadd4. > > > > This is GCC issue, and we should not use `volatile` here. We should disable > > GCC's this optimization for this function via pragma etc. > > https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Specific-Option- > > Pragmas.html#Function-Specific-Option-Pragmas > > https://stackoverflow.com/questions/34436233/fused-multiply-add-and-default- > > rounding-modes > > But these pragmas disable optimization for the whole function. Are you sure > we should disable optimization for the whole function? Yes, we should disable fused multiply add in this function. Using `optimize` function attribute can enforce fp-contract option to this function, I think. > I also tried to use > `#pragma STDC FP_CONTRACT` but gcc doesn't seem to accept it yet: > https://stackoverflow.com/questions/43352510/difference-in-gcc-ffp-contract- > options > > On other platforms that I tested, the compilers already generate an unfused > multiply-add, so we don't seem to be generating worse code either.
Mikhail R. Gadelha
Comment 6 2021-11-10 11:31:36 PST
Yusuke Suzuki
Comment 7 2021-11-10 11:56:30 PST
Comment on attachment 443839 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=443839&action=review > Source/JavaScriptCore/runtime/ParseInt.h:113 > +// Due to a GCC bug found in v8.4.0, a wrong fused multiply-add optimization can be inserted when calculating the final number, > +// in number *= radix; number += digit;, so optimizations are disabled for this functions. > +#pragma GCC push_options > +#pragma GCC optimize ("O0") 1. Why not only disabling fp-contract? We do not need to disable all optimizations. (See comment https://bugs.webkit.org/show_bug.cgi?id=232951#c5) 2. Why not using function attribute? 3. Use it only for GCC. Clang does not need this.
Mikhail R. Gadelha
Comment 8 2021-11-10 12:08:10 PST
(In reply to Yusuke Suzuki from comment #7) > Comment on attachment 443839 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=443839&action=review > > > Source/JavaScriptCore/runtime/ParseInt.h:113 > > +// Due to a GCC bug found in v8.4.0, a wrong fused multiply-add optimization can be inserted when calculating the final number, > > +// in number *= radix; number += digit;, so optimizations are disabled for this functions. > > +#pragma GCC push_options > > +#pragma GCC optimize ("O0") > > 1. Why not only disabling fp-contract? We do not need to disable all > optimizations. (See comment > https://bugs.webkit.org/show_bug.cgi?id=232951#c5) > 2. Why not using function attribute? I just tried adding `__attribute__((optimize("fp-contract=off")))` locally to the function definition and gcc seems to ignore it, i.e., it generates de fma and the test fails. > 3. Use it only for GCC. Clang does not need this.
Yusuke Suzuki
Comment 9 2021-11-10 15:32:44 PST
Comment on attachment 443839 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=443839&action=review >>> Source/JavaScriptCore/runtime/ParseInt.h:113 >>> +#pragma GCC optimize ("O0") >> >> 1. Why not only disabling fp-contract? We do not need to disable all optimizations. (See comment https://bugs.webkit.org/show_bug.cgi?id=232951#c5) >> 2. Why not using function attribute? >> 3. Use it only for GCC. Clang does not need this. > > I just tried adding `__attribute__((optimize("fp-contract=off")))` locally to the function definition and gcc seems to ignore it, i.e., it generates de fma and the test fails. Did you try `GCC optimize` pragma and "fp-contract=off" combination?
Mikhail R. Gadelha
Comment 10 2021-11-10 17:19:24 PST
(In reply to Yusuke Suzuki from comment #9) > Comment on attachment 443839 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=443839&action=review > > >>> Source/JavaScriptCore/runtime/ParseInt.h:113 > >>> +#pragma GCC optimize ("O0") > >> > >> 1. Why not only disabling fp-contract? We do not need to disable all optimizations. (See comment https://bugs.webkit.org/show_bug.cgi?id=232951#c5) > >> 2. Why not using function attribute? > >> 3. Use it only for GCC. Clang does not need this. > > > > I just tried adding `__attribute__((optimize("fp-contract=off")))` locally to the function definition and gcc seems to ignore it, i.e., it generates de fma and the test fails. > > Did you try `GCC optimize` pragma and "fp-contract=off" combination? yep, I'm passing `-ffp-contract=off` in the command line and tried it with both `__attribute__((optimize("fp-contract=off")))` and `__attribute__((optimize("-ffp-contract=off")))`. Neither worked. Maybe it's not working because of the inline attribute? gcc seems to be gracefully ignoring the attribute. I only got it to work it either the `volatile` or `__attribute__((optimize("O0")))`.
Yusuke Suzuki
Comment 11 2021-11-11 21:12:12 PST
Comment on attachment 443839 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=443839&action=review >>>>> Source/JavaScriptCore/runtime/ParseInt.h:113 >>>>> +#pragma GCC optimize ("O0") >>>> >>>> 1. Why not only disabling fp-contract? We do not need to disable all optimizations. (See comment https://bugs.webkit.org/show_bug.cgi?id=232951#c5) >>>> 2. Why not using function attribute? >>>> 3. Use it only for GCC. Clang does not need this. >>> >>> I just tried adding `__attribute__((optimize("fp-contract=off")))` locally to the function definition and gcc seems to ignore it, i.e., it generates de fma and the test fails. >> >> Did you try `GCC optimize` pragma and "fp-contract=off" combination? > > yep, I'm passing `-ffp-contract=off` in the command line and tried it with both `__attribute__((optimize("fp-contract=off")))` and `__attribute__((optimize("-ffp-contract=off")))`. Neither worked. > > Maybe it's not working because of the inline attribute? gcc seems to be gracefully ignoring the attribute. > > I only got it to work it either the `volatile` or `__attribute__((optimize("O0")))`. OK, so at this point, I think the best way is annotating this double with `volatile` *only when it is GCC*. Can you change it? And can you describe the above reasoning in the ChangeLog? (e.g. optimize attribute didn't work etc.).
Mikhail R. Gadelha
Comment 12 2021-11-12 05:36:17 PST
Mikhail R. Gadelha
Comment 13 2021-11-13 05:28:35 PST
Yusuke Suzuki
Comment 14 2021-11-14 00:23:53 PST
Comment on attachment 444136 [details] Patch r=me
EWS
Comment 15 2021-11-14 00:45:51 PST
Committed r285788 (244232@main): <https://commits.webkit.org/244232@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 444136 [details].
Radar WebKit Bug Importer
Comment 16 2021-11-14 00:46:20 PST
Note You need to log in before you can comment on or make changes to this bug.