Skip to content

Emit mustprogress and add --fast-math for loop optimizations/vectorization#198

Merged
ASDAlexander77 merged 2 commits into
mainfrom
codegen/emit-mustprogress-attribute
Jul 11, 2026
Merged

Emit mustprogress and add --fast-math for loop optimizations/vectorization#198
ASDAlexander77 merged 2 commits into
mainfrom
codegen/emit-mustprogress-attribute

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Summary

Two codegen improvements that unlock LLVM's loop optimizations, plus correctness fixes found while validating them.

mustprogress on lowered functions

Lowered functions carried no LLVM function attributes at all. Without mustprogress, the -O2/-O3 loop passes (LICM, unrolling, dead-loop elimination) must conservatively assume any loop may spin forever with no observable effect. Verified with an isolated integer-bounded reduction loop that -O3 previously neither unrolled nor removed when dead.

--fast-math option (opt-in, off by default)

Applies reassoc nsz arcp contract afn fast-math flags to all FP instructions plus matching backend function attributes, before the LLVM optimization pipeline, on every emit path (exe/obj/jit/llvm).

Deliberately excludes nnan/ninf: NaN and Infinity are first-class TypeScript values (Number("abc"), 0/0, overflow), so --fast-math relaxes precision (reassociation, FMA contraction, reciprocal, approx libm) without breaking x !== x NaN checks — verified in optimized IR.

With the flag, a sum += arr[i] double reduction now compiles to <2 x double> wide loads with dual accumulators and llvm.vector.reduce.fadd; without it, codegen stays scalar and IEEE-exact.

PassBuilder now gets a real TargetMachine

All callers passed targetMachine=nullptr to PassBuilder, so the -O3 cost model had no target info — no vector registers known, vectorization never profitable, for anyone. The transformer now builds a TargetMachine from the module triple (honoring -mcpu/-mattr). Benefits all optimized builds independent of fast-math.

NaN predicate correctness fixes (pre-existing bugs)

  • Float !=/!== lowered as fcmp one (ordered): per ECMAScript NaN != x must be true → fixed to une. Previously x !== x (the idiomatic NaN test) folded to constant false at -O3.
  • IsNaNOp lowered as fcmp one x, x, which is constant false for every input → fixed to fcmp uno.
  • 02numbers.ts had codified the buggy behavior (its isnan helper (x !== x) === (x === x) is always false in conforming JS); corrected to the standard x !== x idiom.

New tests

fast_math.ts (compile + jit, run with the new test-runner -fast-math mode which uses separately-cached jitfm/compilefm scripts to avoid poisoning the shared script cache under parallel ctest):

  • FP sum reduction and dot product using exact multiples of 0.125, so every partial sum is exactly representable and reassociation cannot change the result — exact-equality asserts remain valid while exercising the vectorized codepath (verified 14 vector.body blocks in the compiled test).
  • NaN/Infinity semantics under --fast-math (the no-nnan/ninf guarantee).
  • Integer counted loop unaffected.

Test plan

  • Full suite: 683/683 pass (compile + JIT), including the 2 new fast-math tests.
  • Manually verified vectorized IR with --fast-math and scalar IEEE-exact IR without it.
  • Verified NaN checks survive -O3 in both modes.

🤖 Generated with Claude Code

ASDAlexander77 and others added 2 commits July 11, 2026 00:57
Every ts function lowered to LLVM carried no function attributes at
all, including mustprogress. Without it, LLVM's -O2/-O3 loop passes
(LICM, unrolling, vectorization) must stay conservative since they
can't assume a loop terminates or has an observable side effect.
Verified with an isolated integer-bounded reduction loop that -O3
neither unrolled nor vectorized it despite a clean, SCEV-friendly
shape; after this change the attribute is correctly emitted and the
full 681-test suite (compile + JIT) still passes unchanged.

Fast-math flags (needed for FP-reduction vectorization) are
intentionally left out of this change since they'd change IEEE-754
semantics and should be an explicit opt-in, not bundled here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit cd01720 into main Jul 11, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the codegen/emit-mustprogress-attribute branch July 11, 2026 11:01
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