Skip to content

Commit 946da51

Browse files
authored
feat(compiler): implement constant folding for unary minus (facebook#33140)
## Summary `-constant` is represented as a `UnaryExpression` node that is currently not part of constant folding. If the operand is a constant number, the node is folded to `constant * -1`. This also coerces `-0` to `0`, resulting in `0 === -0` being folded to `true`. ## How did you test this change? See attached tests
1 parent a437c99 commit 946da51

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,23 @@ function evaluateInstruction(
327327
}
328328
return null;
329329
}
330+
case '-': {
331+
const operand = read(constants, value.value);
332+
if (
333+
operand !== null &&
334+
operand.kind === 'Primitive' &&
335+
typeof operand.value === 'number'
336+
) {
337+
const result: Primitive = {
338+
kind: 'Primitive',
339+
value: operand.value * -1,
340+
loc: value.loc,
341+
};
342+
instr.value = result;
343+
return result;
344+
}
345+
return null;
346+
}
330347
default:
331348
return null;
332349
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
## Input
3+
4+
```javascript
5+
import {Stringify} from 'shared-runtime';
6+
7+
function foo() {
8+
const a = -1;
9+
return (
10+
<Stringify
11+
value={[
12+
2 * a,
13+
-0,
14+
0 === -0,
15+
-Infinity,
16+
-NaN,
17+
a * NaN,
18+
a * Infinity,
19+
a * -Infinity,
20+
]}
21+
/>
22+
);
23+
}
24+
25+
export const FIXTURE_ENTRYPOINT = {
26+
fn: foo,
27+
params: [],
28+
isComponent: false,
29+
};
30+
31+
```
32+
33+
## Code
34+
35+
```javascript
36+
import { c as _c } from "react/compiler-runtime";
37+
import { Stringify } from "shared-runtime";
38+
39+
function foo() {
40+
const $ = _c(1);
41+
let t0;
42+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
43+
t0 = (
44+
<Stringify
45+
value={[
46+
-2,
47+
0,
48+
true,
49+
-Infinity,
50+
-NaN,
51+
52+
-1 * NaN,
53+
-1 * Infinity,
54+
-1 * -Infinity,
55+
]}
56+
/>
57+
);
58+
$[0] = t0;
59+
} else {
60+
t0 = $[0];
61+
}
62+
return t0;
63+
}
64+
65+
export const FIXTURE_ENTRYPOINT = {
66+
fn: foo,
67+
params: [],
68+
isComponent: false,
69+
};
70+
71+
```
72+
73+
### Eval output
74+
(kind: ok) <div>{"value":[-2,0,true,null,null,null,null,null]}</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {Stringify} from 'shared-runtime';
2+
3+
function foo() {
4+
const a = -1;
5+
return (
6+
<Stringify
7+
value={[
8+
2 * a,
9+
-0,
10+
0 === -0,
11+
-Infinity,
12+
-NaN,
13+
a * NaN,
14+
a * Infinity,
15+
a * -Infinity,
16+
]}
17+
/>
18+
);
19+
}
20+
21+
export const FIXTURE_ENTRYPOINT = {
22+
fn: foo,
23+
params: [],
24+
isComponent: false,
25+
};

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/constant-propagation-unary.expect.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function foo() {
5858
n0: true,
5959
n1: false,
6060
n2: false,
61-
n3: !-1,
61+
n3: false,
6262
s0: true,
6363
s1: false,
6464
s2: false,

0 commit comments

Comments
 (0)