Emit mustprogress and add --fast-math for loop optimizations/vectorization#198
Merged
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 afnfast-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-mathrelaxes precision (reassociation, FMA contraction, reciprocal, approx libm) without breakingx !== xNaN 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 andllvm.vector.reduce.fadd; without it, codegen stays scalar and IEEE-exact.PassBuilder now gets a real TargetMachine
All callers passed
targetMachine=nullptrtoPassBuilder, 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)
!=/!==lowered asfcmp one(ordered): per ECMAScriptNaN != xmust betrue→ fixed toune. Previouslyx !== x(the idiomatic NaN test) folded to constantfalseat -O3.IsNaNOplowered asfcmp one x, x, which is constant false for every input → fixed tofcmp uno.02numbers.tshad codified the buggy behavior (itsisnanhelper(x !== x) === (x === x)is always false in conforming JS); corrected to the standardx !== xidiom.New tests
fast_math.ts(compile + jit, run with the newtest-runner -fast-mathmode which uses separately-cachedjitfm/compilefmscripts to avoid poisoning the shared script cache under parallel ctest):vector.bodyblocks in the compiled test).--fast-math(the no-nnan/ninf guarantee).Test plan
--fast-mathand scalar IEEE-exact IR without it.🤖 Generated with Claude Code