GHC WebAssembly Weekly Update, 2023-04-12

Testsuite update

The good news is: the number of remaining unexpected failures halved since last report, about ~40 right now! The bad news is: the rest of them mostly conforms to a failure pattern that’s reproducible but still makes me scratch my hair:

  • Some cases fail when run by the testsuite driver, but pass (exit code 0, matches expected stdout/stderr) otherwise
  • Some cases fail in wasmtime (wasi-common) but work in nodejs (uvwasi), some otherwise
  • Failures above are mostly EPERM errors of certain file descriptors when the Haskell code does some I/O and the request eventually goes through the poll_oneoff wasi syscall, which will almost surely translate to a poll/epoll syscall in the host system.

To avoid dropping into another deep rabbit hole and missing the bigger picture, I’ll set up a tracking issue for them and mark them as fragile for the time being, if I don’t make more sense of them in a week or so.

Wasm NCG panic bugfix

I was a bit too early to open the champagne for running out of codegen bugs! There’s a wasm NCG compiler panic bug (#23237) reported by @amesgen, triggered by a single repro module he helpfully minimized from a package.

I shrinked that repro to a single Haskell function, then shrinked the offending Cmm file to a single Cmm function. At which point it becomes obvious: it’s an irreducible control-flow graph that choked our NCG. Irreducible CFGs are rather rare in the GHC pipeline, but other than hand-written Cmm files, they may still occur from the result of compiling Haskell functions.

Norman implemented the node-splitting algorithm to convert irreducible CFGs to reducible ones, but it turns out that it wasn’t rightfully applied to all CmmGraphs that the wasm NCG consumes, so I landed the patch (!10256) to fix it. In case you’re interested in why we need some fancy logic to deal with CFGs when lowering Cmm to wasm, Norman’s ICFP’22 paper Beyond Relooper is an excellent introduction.

I’d also like to take this chance to mention creduce, an invaluable tool for minimizing repros when debugging a compiler. The idea is simple: take a starting program that satisfies an interesting property (e.g. triggers a compiler crash containing a certain error message), and a script that tests that property, creduce then mutates and shrinks that program to a minimum. Despite its name, it can shrink any text files other than C/C++, and I’ve had success shrinking many things in my day job: LLVM IR, shell scripts, assembly files, etc. This time it works surprisingly well for Haskell. Go give it a try if you have any text file that reproduces a bug you’re dealing with, worst case scenario is just a rather long coffee break!

11 Likes