Repository: swc-project/swc (rust)

Issue:
minifier: Evaluates value of `Math.min`/`Math.max` incorrectly in different argument order
### Describe the bug

The inlined result should be same even if the argument order is changed.

### Input code

```typescript
console.log(Math.min(-0, 0))
console.log(Math.min(0, -0))
console.log(Math.max(-0, 0))
console.log(Math.max(0, -0))
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "jsx": false
    },
    "target": "es5",
    "loose": false,
    "minify": {
      "compress": {
        "arguments": false,
        "arrows": true,
        "booleans": true,
        "booleans_as_integers": false,
        "collapse_vars": true,
        "comparisons": true,
        "computed_props": true,
        "conditionals": true,
        "dead_code": true,
        "directives": true,
        "drop_console": false,
        "drop_debugger": true,
        "evaluate": true,
        "expression": false,
        "hoist_funs": false,
        "hoist_props": true,
        "hoist_vars": false,
        "if_return": true,
        "join_vars": true,
        "keep_classnames": false,
        "keep_fargs": true,
        "keep_fnames": false,
        "keep_infinity": false,
        "loops": true,
        "negate_iife": true,
        "properties": true,
        "reduce_funcs": false,
        "reduce_vars": false,
        "side_effects": true,
        "switches": true,
        "typeofs": true,
        "unsafe": false,
        "unsafe_arrows": false,
        "unsafe_comps": false,
        "unsafe_Function": false,
        "unsafe_math": false,
        "unsafe_symbols": false,
        "unsafe_methods": false,
        "unsafe_proto": false,
        "unsafe_regexp": false,
        "unsafe_undefined": false,
        "unused": true,
        "const_to_let": true,
        "pristine_globals": true
      },
      "mangle": {
        "toplevel": false,
        "keep_classnames": false,
        "keep_fnames": false,
        "keep_private_props": false,
        "ie8": false,
        "safari10": false
      }
    }
  },
  "module": {
    "type": "commonjs"
  },
  "minify": false,
  "isModule": true
}
```


### Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.5.24&code=H4sIAAAAAAAAA0vOzyvOz0nVy8lP1%2FBNLMnQy83M09A10FEw0NTkSsYmCZTTxS6ZWIFHJ1ASqhMARowy1HMAAAA%3D&config=H4sIAAAAAAAAA42VzW7bMAyA732KwOcdtsOAYg%2Bw255BUCzKUSaJhkilCYq8%2B2jFTtOGNnYJYn78ESmSen%2FZ7boj9d2v3bv8lY%2FRFoJy%2FxYJXTLbs0g66JOlvoSRu28LPdKEvI0ETXS9kY5tGYCbFf2c1buISLCoz7IUcvCXx4A9prEA0YNMpOKvJshMn%2B1nVvBtAlzqo3yPGMHmDWIsmZAZBiia4x5jtCOBOdmieJlOaksg1EJMsDI4MxYcVZ5d4IBZYj5TB9aZHh0oKBToOZxAM5NYYpZJ0lPyadjBvg5Du%2BQv1nCysVpWYsK5XYmcVvF6wEBsfM1aCW9wpQY3OBf3q2XwpgDXkp%2Ftjhjyyp38BZAKREuUbQLNb9Pw0k9r1n7TMmQvLcsXhUt%2Fa1lmGKSoJgSvVHaqDBQO2m0WcLWHqbK9dpwZr5SPggMD3kuvKK7pLXB%2F0ILyZQT0CpD7tV7rqhsw9ylc4dNAbODfkiXrDTZrJMuHdUqXtMe4ESABH9BtKMhVMK7jIlviPK7zmh1Ia4BTVSo18LwEZAAYTWzL8qk3ZDzEoxki7j%2FWxKxwvS%2FhZPPQ5v1hXzKOEU4Q19r4P0Zkk8rZTlNXL5P9NL3wqjWllcELP75%2FejMklZfltyXVJXT1IaHWk9NbIi2UMB%2Bp%2B9Bcno97pC7Qn8W8Vev6D4dGmLPmBgAA

### SWC Info output

_No response_

### Expected behavior

```javascript
console.log(-0)
console.log(-0)
console.log(0)
console.log(0)
```

### Actual behavior

```javascript
console.log(0)
console.log(-0)
console.log(-0)
console.log(0)
```

### Version

1.5.24

### Additional context

_No response_

Pull request:
fix(es/minifier): Fix comparison of `-0.0`
**Description:**


**Related issue:**

 - Closes #9007

Patch:
diff --git a/crates/swc_ecma_minifier/src/compress/util/mod.rs b/crates/swc_ecma_minifier/src/compress/util/mod.rs
index eed2bbc304..8ed2d15a78 100644
--- a/crates/swc_ecma_minifier/src/compress/util/mod.rs
+++ b/crates/swc_ecma_minifier/src/compress/util/mod.rs
@@ -760,12 +760,12 @@ impl Visit for SuperFinder {
 }
 
 fn cmp_num(a: f64, b: f64) -> Ordering {
-    if a == -0.0 && b == 0.0 {
-        return Ordering::Greater;
+    if a == 0.0 && a.is_sign_negative() && b == 0.0 && b.is_sign_positive() {
+        return Ordering::Less;
     }
 
-    if a == 0.0 && b == -0.0 {
-        return Ordering::Less;
+    if a == 0.0 && a.is_sign_positive() && b == 0.0 && b.is_sign_negative() {
+        return Ordering::Greater;
     }
 
     a.partial_cmp(&b).unwrap()


Test patch:
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/9007/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/9007/input.js
new file mode 100644
index 0000000000..4cb74ed269
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/9007/input.js
@@ -0,0 +1,4 @@
+console.log(Math.min(-0, 0))
+console.log(Math.min(0, -0))
+console.log(Math.max(-0, 0))
+console.log(Math.max(0, -0))
\ No newline at end of file
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/9007/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/9007/output.js
new file mode 100644
index 0000000000..4861fafca5
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/9007/output.js
@@ -0,0 +1,1 @@
+console.log(-0), console.log(-0), console.log(0), console.log(0);