Skip to content
Merged
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
6 changes: 1 addition & 5 deletions src/ir/constraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,7 @@ void BasicBlockConstraintMap::set(Index index, const Constraint& c) {

// Clear the old state.
eraseStaleRefs(index);
map[index].setProvesNothing();
// Note that this last line puts us in a temporarily invalid state: we do not
// normally store a constraint of proves-nothing in the map. Doing it this
// way, until approximateAnd adds the constraint, is more efficient than
// erasing and re-adding.
map.erase(index);

// Apply the constraint.
approximateAnd(index, c);
Expand Down
8 changes: 5 additions & 3 deletions src/passes/ConstraintAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,14 @@ struct ConstraintAnalysis
// of course not needed at this stage.)
auto& constraints = block->contents.startConstraints;
for (auto** currp : block->contents.actions) {
applyToConstraints(*currp, constraints);
if (constraints.unreachable) {
if (!constraints.unreachable) {
applyToConstraints(*currp, constraints);
optimizeExpression(currp, constraints);
} else {
// This is unreachable code: just mark it so.
*currp = Builder(*getModule()).makeUnreachable();
refinalize = true;
}
optimizeExpression(currp, constraints);
}
}

Expand Down
58 changes: 58 additions & 0 deletions test/lit/passes/constraint-analysis.wast
Original file line number Diff line number Diff line change
Expand Up @@ -3472,4 +3472,62 @@
(br $loop)
)
)

;; CHECK: (func $unreachable-loop (type $1)
;; CHECK-NEXT: (local $x i32)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; OPTIN: (func $unreachable-loop (type $1)
;; OPTIN-NEXT: (local $x i32)
;; OPTIN-NEXT: (unreachable)
;; OPTIN-NEXT: (unreachable)
;; OPTIN-NEXT: )
(func $unreachable-loop
(local $x i32)
;; The entire loop is unreachable. The control flow here should not cause any
;; internal errors, and we can just optimize this to unreachable.
(unreachable)
(local.set $x
(loop $loop (result i32)
(i32.const 0)
)
)
)

;; CHECK: (func $set-silly (type $0) (param $x i32)
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (then
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; OPTIN: (func $set-silly (type $0) (param $x i32)
;; OPTIN-NEXT: (local.set $x
;; OPTIN-NEXT: (local.get $x)
;; OPTIN-NEXT: )
;; OPTIN-NEXT: (if
;; OPTIN-NEXT: (i32.const 0)
;; OPTIN-NEXT: (then
;; OPTIN-NEXT: )
;; OPTIN-NEXT: )
;; OPTIN-NEXT: )
(func $set-silly (param $x i32)
;; Setting x to x adds no information, and we do not store it in the IR. This
;; must not lead to internal errors (we have asserts on not storing
;; "proves-nothing" in the internal map, and if we wrote this, it would be
;; that).
(local.set $x
(local.get $x)
)
;; Add some control flow to exercise the assert.
(if
(i32.const 0)
(then)
)
)
)

Loading