Skip to content

Skip statically dead branches of ?:, && and while - #327

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fold-static-typeof-other-conditions
Sep 14, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
fold-static-typeof-other-conditions

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Problem

#324 stopped if from generating the branch of a typeof x === "name" test that folds to a constant. ?:, && and while still generated that branch together with its narrowing. In a generic specialised for an array, typeof x === "string" ? x.length : -1 cast the array to string. Under --di (always passed by the test runner) the narrowed variable's debug record kept that cast alive until LLVM lowering, where a debug build hits llvm_unreachable in CastLogicHelper.h:815. Release builds compile the check out, so CI never saw it.

Fix

  • getStaticBoolean() recognises a condition known at compile time: a boolean literal, also through casts to boolean. if uses it too.
  • ?: and false && right don't generate the dead branch. It is evaluated, narrowing included, in the temporary module to keep its type, and the branch yields an undefined value of that type, so the expression's type is unchanged. A boolean false && right returns the constant condition itself, so an enclosing if/while sees that it is known.
  • while with a condition known to be false doesn't generate its body.

|| never narrows and was not affected.

Tests

New 00typeof_static_fold_conditions.ts (compile, JIT and corpus variants): ?: in both orders, &&, while (typeof x === "string" && ...), each for a string and an array, plus a check that a skipped ?: branch still contributes its type.

Full Windows debug suite (ctest -R "^test-"): 2739/2739 passed.

Not addressed (pre-existing)

  • if (typeof genericFn === "function") on an uninstantiated generic function fails lowering ("llvm.mlir.addressof op must reference a global"): narrowing casts a reference to the never-emitted generic.
  • let v = b ? 1 : "one" types v as the literal union 1 | "one" and warns "types have different sizes", with a runtime condition as well.

🤖 Generated with Claude Code

#324 stopped `if` from generating the branch of a `typeof x === "name"` test
that folds to a constant. `?:`, `&&` and `while` still generated it, with its
narrowing: in a generic specialised for an array, `typeof x === "string" ?
x.length : -1` cast the array to string, and under --di the narrowed
variable's debug record kept that cast alive until LLVM lowering, which hit
llvm_unreachable in CastLogicHelper.

- getStaticBoolean() recognises a constant condition, also through casts to
  boolean (a folded typeof, or an `&&` whose left side folded to false);
  `if` uses it too.
- ?: and `false && right` evaluate the dead branch, narrowing included, in
  the temporary module to keep its type, and yield an undefined value of
  that type; the expression's type is unchanged. A boolean `false && right`
  is just the constant condition, so an enclosing if/while sees it too.
- `while` with a false constant condition does not generate its body.

`||` does not narrow and was not affected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit a47ccdd into main Sep 14, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fold-static-typeof-other-conditions branch September 14, 2026 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant