fixed

Pure Haskell large fixed-width integers and Montgomery arithmetic (docs.ppad.tech/fixed).
git clone git://git.ppad.tech/fixed.git
Log | Files | Refs | README | LICENSE

commit 533281ee35a0ab32fdd3d2cb0a2b058ec3b0e6f2
parent e303bda7578385f488c2f23baa2e1a6a2b0b2aaf
Author: Jared Tobin <jared@jtobin.io>
Date:   Tue, 27 Oct 2026 17:34:29 +0400

merge impl/cmov-converter: LLVM's x86 cmov converter off under the llvm flag

On x86_64, LLVM compiled the borrow-masked correction of sub_mod,
sub_mod#, and sub_mod_c# as a branch on the borrow: InstCombine forms
a select from the mask, the x86 backend a cmov, and its cmov
converter rewrites a cmov whose operand is a load (the modulus, read
from the boxed Wider or the stack) as a branch. A differential trace
of sub_mod showed the branch splitting sixteen secrets eight and
eight.

The library's llvm flag now passes -optlc=-x86-cmov-converter=false
on x86_64, which keeps the four cmovs (on Intel's DOIT list). No
other module's code changes; NCG builds and aarch64 were unaffected.
The tests pass under the flag on x86_64, and the same trace shows no
origin.

Diffstat:
MCHANGELOG | 8++++++++
Mppad-fixed.cabal | 5+++++
2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -1,5 +1,13 @@ # Changelog +- unreleased + * Under the llvm flag on x86_64, the library is compiled with LLVM's + x86 cmov converter off (-optlc=-x86-cmov-converter=false). The + converter rewrites a conditional move whose operand is a load as a + branch, and so made the borrow-masked correction of sub_mod, + sub_mod#, and sub_mod_c# a branch on the borrow, which depends on + the operands. NCG builds, and aarch64, were unaffected. + - 0.2.0 (2026-08-01) * Addresses a couple of minor issues detected by an LLM scan: diff --git a/ppad-fixed.cabal b/ppad-fixed.cabal @@ -31,6 +31,11 @@ library -Wall if flag(llvm) ghc-options: -fllvm -O2 + -- LLVM's x86 backend rewrites a cmov whose operand is a load as a + -- branch (its cmov converter), which makes sub_mod#'s borrow-masked + -- correction a branch on the borrow; keep the cmov. + if flag(llvm) && arch(x86_64) + ghc-options: -optlc=-x86-cmov-converter=false exposed-modules: Data.Choice , Data.Word.Limb