Bug 194250 - B3ReduceStrength: missing peephole optimizations for Neg and Sub
Summary: B3ReduceStrength: missing peephole optimizations for Neg and Sub
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Robin Morisset
URL:
Keywords: InRadar
Depends on:
Blocks: 154319 194420
  Show dependency treegraph
 
Reported: 2019-02-04 16:22 PST by Robin Morisset
Modified: 2019-02-07 16:32 PST (History)
7 users (show)

See Also:


Attachments
Patch (6.02 KB, patch)
2019-02-04 17:12 PST, Robin Morisset
no flags Details | Formatted Diff | Diff
Patch (13.57 KB, patch)
2019-02-05 13:19 PST, Robin Morisset
no flags Details | Formatted Diff | Diff
Patch (13.03 KB, patch)
2019-02-06 16:08 PST, Robin Morisset
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Robin Morisset 2019-02-04 16:22:02 PST
In particular:
- Sub(x, x) => 0
- Sub(x1, Neg(x2)) => Add (x1, x2)
- Abs(Neg(x)) => Abs(x)
- Neg(Sub(x1, x2)) => Sub(x2, x1)
- Add(x1, Neg(x2)) => Sub(x1, x2)
- Add(Neg(x1), x2) => Sub(x2, x1)

I don't expect the performance benefit to be significant, but this is very low-hanging fruit.
Comment 1 Robin Morisset 2019-02-04 17:12:19 PST
Created attachment 361134 [details]
Patch
Comment 2 Saam Barati 2019-02-04 17:15:39 PST
Comment on attachment 361134 [details]
Patch

Can you add B3 tests for each of these?
Comment 3 Saam Barati 2019-02-04 17:24:14 PST
Comment on attachment 361134 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=361134&action=review

> Source/JavaScriptCore/b3/B3ReduceStrength.cpp:584
> +                // Turn this: Integer Add(value, Neg(otherValue))
> +                // Into this: Sub(value, otherValue)

Does this actually need to only be done on Int types?

> Source/JavaScriptCore/b3/B3ReduceStrength.cpp:591
> +                // Turn this: Integer Add(Neg(value), otherValue)
> +                // Into this: Sub(otherValue, value)

Ditto

> Source/JavaScriptCore/b3/B3ReduceStrength.cpp:642
> +                // Turn this: Sub(value, Neg(otherValue))
> +                // Into this: Add(value, otherValue)

Can this also be done for floating point types?
Comment 4 Robin Morisset 2019-02-04 17:40:17 PST
(In reply to Saam Barati from comment #3)
> Comment on attachment 361134 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=361134&action=review
> 
> > Source/JavaScriptCore/b3/B3ReduceStrength.cpp:584
> > +                // Turn this: Integer Add(value, Neg(otherValue))
> > +                // Into this: Sub(value, otherValue)
> 
> Does this actually need to only be done on Int types?
> 
> > Source/JavaScriptCore/b3/B3ReduceStrength.cpp:591
> > +                // Turn this: Integer Add(Neg(value), otherValue)
> > +                // Into this: Sub(otherValue, value)
> 
> Ditto
> 
> > Source/JavaScriptCore/b3/B3ReduceStrength.cpp:642
> > +                // Turn this: Sub(value, Neg(otherValue))
> > +                // Into this: Add(value, otherValue)
> 
> Can this also be done for floating point types?

I am not entirely sure, and I decided to play it safe. The following sentence in particular scares me:
"Because of negative zero (and also when the rounding mode is upward or downward), the expressions −(x − y) and (−x) − (−y), for floating-point variables x and y, cannot be replaced by y − x. However (−0) + x can be replaced by x with rounding to nearest (except when x can be a signaling NaN)." (from https://en.wikipedia.org/wiki/Signed_zero).
I am not familiar enough with the subtleties of floating point arithmetic to try to do anything smart with floats. While checking again, I realized I made the mistake above (i.e. forgot checking the type for Neg(Sub(x1, x2)) => Sub(x2, x1).

I will submit soon a new patch with this bug fixed, and tests (I did not know about testB3.cpp, it should make it easy).
Comment 5 Robin Morisset 2019-02-05 13:19:11 PST
Created attachment 361215 [details]
Patch
Comment 6 Robin Morisset 2019-02-05 13:36:17 PST
Note: There are exactly two optimizations affecting floats/doubles in this patch:
- Abs(Neg(x)) => Abs(x)
  This seems right to me, as Abs(x) always remove the sign bit and Neg just flips it, so even things like negative 0 should not be able to cause any trouble.
- Sub(x, x) => +0.0
   Based on wikipedia: "x-x=x+(-x)=+0 (for any finite x, −0 when rounding toward negative)"
    I assumed that we don't mess with the rounding mode, and it passed the tests. But if we ever decide to round towards negative, we will have to change/remove this optimization.
Comment 7 Saam Barati 2019-02-06 13:39:23 PST
Comment on attachment 361215 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=361215&action=review

> Source/JavaScriptCore/b3/B3ReduceStrength.cpp:617
> +            // Turn this: Sub(value, value)

I don’t think this is correct for NaN, right?
I think NaN - NaN = NaN
Comment 8 Robin Morisset 2019-02-06 14:17:15 PST
(In reply to Saam Barati from comment #7)
> Comment on attachment 361215 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=361215&action=review
> 
> > Source/JavaScriptCore/b3/B3ReduceStrength.cpp:617
> > +            // Turn this: Sub(value, value)
> 
> I don’t think this is correct for NaN, right?
> I think NaN - NaN = NaN

Good catch, I will remove this case. But I must first understand why it was not caught by the tests.
It should have been found by testSubArgDouble, as it is called on PNaN through 
RUN_UNARY(testSubArgDouble, floatingPointOperands<double>());
as floatingPointOperands<double> includes PNaN.

So I added some instrumentation.. and it appears that testB3 does not ever call B3ReduceStrength :-(. I'm currently looking into it.
Comment 9 Robin Morisset 2019-02-06 15:19:12 PST
(In reply to Robin Morisset from comment #8)
> (In reply to Saam Barati from comment #7)
> > Comment on attachment 361215 [details]
> > Patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=361215&action=review
> > 
> > > Source/JavaScriptCore/b3/B3ReduceStrength.cpp:617
> > > +            // Turn this: Sub(value, value)
> > 
> > I don’t think this is correct for NaN, right?
> > I think NaN - NaN = NaN
> 
> Good catch, I will remove this case. But I must first understand why it was
> not caught by the tests.
> It should have been found by testSubArgDouble, as it is called on PNaN
> through 
> RUN_UNARY(testSubArgDouble, floatingPointOperands<double>());
> as floatingPointOperands<double> includes PNaN.
> 
> So I added some instrumentation.. and it appears that testB3 does not ever
> call B3ReduceStrength :-(. I'm currently looking into it.

I had simply forgotten to set DYLD_FRAMEWORK_PATH before running testB3, so it was running some system version of jsc, instead of my broken one..
Comment 10 Robin Morisset 2019-02-06 16:08:02 PST
Created attachment 361341 [details]
Patch
Comment 11 Saam Barati 2019-02-06 19:58:15 PST
Comment on attachment 361341 [details]
Patch

Nice. r=me
Comment 12 WebKit Commit Bot 2019-02-07 10:36:41 PST
Comment on attachment 361341 [details]
Patch

Clearing flags on attachment: 361341

Committed r241126: <https://trac.webkit.org/changeset/241126>
Comment 13 WebKit Commit Bot 2019-02-07 10:36:43 PST
All reviewed patches have been landed.  Closing bug.
Comment 14 Radar WebKit Bug Importer 2019-02-07 10:38:17 PST
<rdar://problem/47888576>