Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/int-identity-ops.polish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Compile integer `x + 0`, `0 + x`, `x - 0`, `x * 1`, `1 * x` and `x / 1` to `x`. https://github.com/rescript-lang/rescript/pull/8871
18 changes: 15 additions & 3 deletions compiler/core/js_exp_make.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1595,10 +1595,18 @@ and float_minus ?comment (e1 : t) (e2 : t) : t =
| Number (Int {i; _}), Number (Int {i = j; _}) -> int ?comment (Int32.sub i j)
| _ -> {comment; source_loc = None; expression_desc = Bin (Minus, e1, e2)}

let int32_add ?comment e1 e2 = to_int32 (float_add ?comment e1 e2)
(* An operand of an int operation is an int32 value, so an identity
operation ([x + 0], [x - 0], [x * 1], [x / 1]) is the operand itself. *)
let int32_add ?comment (e1 : t) (e2 : t) : t =
match (e1.expression_desc, e2.expression_desc) with
| _, Number (Int {i = 0l}) -> e1
| Number (Int {i = 0l}), _ -> e2
| _ -> to_int32 (float_add ?comment e1 e2)

let int32_minus ?comment e1 e2 : J.expression =
to_int32 (float_minus ?comment e1 e2)
let int32_minus ?comment (e1 : t) (e2 : t) : J.expression =
match e2.expression_desc with
| Number (Int {i = 0l}) -> e1
| _ -> to_int32 (float_minus ?comment e1 e2)

let float_div ?comment e1 e2 = bin ?comment Div e1 e2
let float_pow ?comment e1 e2 = bin ?comment Pow e1 e2
Expand All @@ -1610,6 +1618,7 @@ let int32_asr ?comment e1 e2 : J.expression =
let int32_div ~checked ?comment (e1 : t) (e2 : t) : t =
match (e1.expression_desc, e2.expression_desc) with
| Length _, Number (Int {i = 2l}) -> int32_asr e1 one_int_literal
| _, Number (Int {i = 1l}) -> e1
| e1_desc, Number (Int {i = i1}) when i1 <> 0l -> (
match e1_desc with
| Number (Int {i = i0}) -> int (Int32.div i0 i1)
Expand Down Expand Up @@ -1654,6 +1663,9 @@ let int32_mul ?comment (e1 : J.expression) (e2 : J.expression) : J.expression =
| ( {expression_desc = Number (Int {i = i0}); _},
{expression_desc = Number (Int {i = i1}); _} ) ->
int (Int32.mul i0 i1)
| e, {expression_desc = Number (Int {i = 1l}); _}
| {expression_desc = Number (Int {i = 1l}); _}, e ->
e
| e, {expression_desc = Number (Int {i = i0}); _}
| {expression_desc = Number (Int {i = i0}); _}, e ->
let i = is_pos_pow i0 in
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/tests/src/gpr_3609_test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function func(state) {
if (typeof state !== "object") {
return 0;
} else {
return 0 + state._0 | 0;
return state._0;
}
}

Expand Down
69 changes: 69 additions & 0 deletions tests/tests/src/int_identity_ops_test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Mocha from "mocha";
import * as Test_utils from "./test_utils.mjs";

function addZero(x) {
return x;
}

function zeroAdd(x) {
return x;
}

function subZero(x) {
return x;
}

function mulOne(x) {
return x;
}

function oneMul(x) {
return x;
}

function divOne(x) {
return x;
}

let calls = {
contents: 0
};

function next() {
calls.contents = calls.contents + 1 | 0;
return calls.contents;
}

function effectful() {
return next();
}

Mocha.describe("Int_identity_ops_test", () => {
Mocha.test("identity operations return the operand", () => {
Test_utils.eq("File \"int_identity_ops_test.res\", line 21, characters 7-14", 7, 7);
Test_utils.eq("File \"int_identity_ops_test.res\", line 22, characters 7-14", -7, -7);
Test_utils.eq("File \"int_identity_ops_test.res\", line 23, characters 7-14", 2147483647, 2147483647);
Test_utils.eq("File \"int_identity_ops_test.res\", line 24, characters 7-14", -2147483648, -2147483648);
Test_utils.eq("File \"int_identity_ops_test.res\", line 25, characters 7-14", 42, 42);
Test_utils.eq("File \"int_identity_ops_test.res\", line 26, characters 7-14", -5, -5);
});
Mocha.test("the operand is evaluated once", () => {
Test_utils.eq("File \"int_identity_ops_test.res\", line 29, characters 7-14", effectful(), 1);
Test_utils.eq("File \"int_identity_ops_test.res\", line 30, characters 7-14", calls.contents, 1);
});
});

export {
addZero,
zeroAdd,
subZero,
mulOne,
oneMul,
divOne,
calls,
next,
effectful,
}
/* Not a pure module */
32 changes: 32 additions & 0 deletions tests/tests/src/int_identity_ops_test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
open Mocha
open Test_utils

let addZero = (x: int) => x + 0
let zeroAdd = (x: int) => 0 + x
let subZero = (x: int) => x - 0
let mulOne = (x: int) => x * 1
let oneMul = (x: int) => 1 * x
let divOne = (x: int) => x / 1

let calls = ref(0)
let next = () => {
calls := calls.contents + 1
calls.contents
}

let effectful = () => next() * 1 + 0

describe(__MODULE__, () => {
test("identity operations return the operand", () => {
eq(__LOC__, addZero(7), 7)
eq(__LOC__, zeroAdd(-7), -7)
eq(__LOC__, subZero(2147483647), 2147483647)
eq(__LOC__, mulOne(-2147483648), -2147483648)
eq(__LOC__, oneMul(42), 42)
eq(__LOC__, divOne(-5), -5)
})
test("the operand is evaluated once", () => {
eq(__LOC__, effectful(), 1)
eq(__LOC__, calls.contents, 1)
})
})
Loading