Bug 263882 - ValueMod is eliminated incorrectly which changes the semantics of the JavaScript program
Summary: ValueMod is eliminated incorrectly which changes the semantics of the JavaScr...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: PC Linux
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2023-10-30 05:23 PDT by EntryHi
Modified: 2023-11-06 04:24 PST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description EntryHi 2023-10-30 05:23:33 PDT
=======================test.js============
function main() {
  for (let v36 = 0; v36 < 1000; v36++) {
    try {
      1n % 0n            
    } catch (ee) {
      print("hello")
    }
  }
}

main()
==========================================

Run args: ./jsc -f test.js --useConcurrentJIT=0  --jitPolicyScale=0

JSC should print 1000 "hello", but it actually only print two.

This bug is related to DCE and DFGMovHintRemovalPhase which is similar to bug263881.

However, these two bugs execute different conditions in DFGMovHintRemovalPhase.cpp:

```
            if (node->op() == MovHint) {
                Epoch localEpoch = m_state.operand(node->unlinkedOperand());
                if (DFGMovHintRemovalPhaseInternal::verbose)
                    dataLog("    At ", node, " (", node->unlinkedOperand(), "): current = ", currentEpoch, ", local = ", localEpoch, "\n");
                if (!localEpoch || localEpoch == currentEpoch) {
                    // Now, MovHint will put bottom value to dead locals. This means that if you insert a new DFG node which introduce
                    // a new OSR exit, then it gets confused with the already-determined-dead locals. So this phase runs at very end of
                    // DFG pipeline, and we do not insert a node having a new OSR exit (if it is existing OSR exit, or if it does not exit,
                    // then it is totally fine).
                    node->setOpAndDefaultFlags(ZombieHint);
                    UseKind useKind = node->child1().useKind();
                    Node* constant = m_constants.ensure(static_cast<std::underlying_type_t<UseKind>>(useKind), [&]() -> Node* {
                        return m_insertionSet.insertBottomConstantForUse(0, m_graph.block(0)->at(0)->origin, useKind).node();
                    }).iterator->value;
                    node->child1() = Edge(constant, useKind);
                    m_changed = true;
                }
                m_state.operand(node->unlinkedOperand()) = Epoch();
            }
```

In this bug, the `localEpoch` of `MovHint` for `ValueMod` is none. In bug263881, the `localEpoch` of `MovHint` for `BitURShift` equals currentEpoch.
Comment 1 Radar WebKit Bug Importer 2023-11-06 04:24:13 PST
<rdar://problem/117993620>