From db80cae8336aa43fd9ac72e2566a49c265b426fc Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Aug 2026 16:35:02 -0700 Subject: [PATCH] fix --- src/passes/ConstraintAnalysis.cpp | 8 ++- .../lit/passes/constraint-analysis-loops.wast | 53 +++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/passes/ConstraintAnalysis.cpp b/src/passes/ConstraintAnalysis.cpp index 324e2ef0312..a3bfbb11808 100644 --- a/src/passes/ConstraintAnalysis.cpp +++ b/src/passes/ConstraintAnalysis.cpp @@ -655,13 +655,17 @@ struct ConstraintAnalysis if (branch.constraint.op == Abstract::LtS || branch.constraint.op == Abstract::LeS) { constraints.set(branch.local, branch.constraint); - constraints.approximateAnd(branch.local, {GeS, {*N}}); + if (!constraints.unreachable) { + constraints.approximateAnd(branch.local, {GeS, {*N}}); + } return true; } if (branch.constraint.op == Abstract::LtU || branch.constraint.op == Abstract::LeU) { constraints.set(branch.local, branch.constraint); - constraints.approximateAnd(branch.local, {GeU, {*N}}); + if (!constraints.unreachable) { + constraints.approximateAnd(branch.local, {GeU, {*N}}); + } return true; } diff --git a/test/lit/passes/constraint-analysis-loops.wast b/test/lit/passes/constraint-analysis-loops.wast index a865c5b8651..8b6513d4dcd 100644 --- a/test/lit/passes/constraint-analysis-loops.wast +++ b/test/lit/passes/constraint-analysis-loops.wast @@ -1520,4 +1520,57 @@ ) ) ) + + ;; CHECK: (func $impossible-branch (type $0) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (loop $loop + ;; CHECK-NEXT: (br_if $loop + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $impossible-branch + (local $x i32) + (local $y i32) + (loop $loop + ;; x == y == 0, so x < y leads to a contradiction, and we never branch + ;; back up to the loop. We should not error here. + (br_if $loop + (i32.lt_s + (local.get $x) + (local.get $y) + ) + ) + ) + ) + + ;; CHECK: (func $impossible-branch-unsigned (type $0) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (loop $loop + ;; CHECK-NEXT: (br_if $loop + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $impossible-branch-unsigned + (local $x i32) + (local $y i32) + ;; As above, but unsigned. + (loop $loop + (br_if $loop + (i32.lt_u + (local.get $x) + (local.get $y) + ) + ) + ) + ) )