So the problem here is that the division overflows a 16-bit word. That is, the bit pattern 0x8000 represents the signed value -32768. Naturally, -32768/-1 == 32768, which is not representable as a 16-bit integer (which can only represent [-32768, +32767]).
So the problem here is that the division overflows a 16-bit word.
To expand on this. I vaguely remember that this will silently overflow on some platforms (aarch64), and raise an exception on others (x86). (I verified the x86 behaviour only).
It seems sensible to define the result for signed division machops as undefined when it overflows, and adapt test-primops to avoid generating such cases.
Yes, signed integer divison has undefined behavior on overflow at the PrimOp and MachOp level, and this should be better-documented. See also discussion at ghc#24556.
I have looked into this. We already excluded overflowing signed division in the Arbitrary generator. However, it looks like I failed to include this same logic in the shrinker. I have fixed this in !29 (merged).
However, the fact that the shrinker was being used at all is suggestive that there may be a bug in our handling of pext.
I suspect that the culprit here is actually the C implementation (libraries/ghc-internal/cbits/pext.c) used when BMI2 is not enabled as I cannot reproduce the issue with -mbmi2. It is not obvious what is wrong with it, however.
I'm new to this project, so I may be saying something silly...
The type for %pext32 is (bits64, bits64) -> bits64 on 64-bit platforms, right?
But, if I understand correctly, the test suite passes (bits32, bits32) to %pext32.
If I run ./run.sh --ghc-args -dcmm-lint, I get many Cmm lint errors.
I think this problem can be solved by one of the following ways:
Change the test to pass (bits64, bits64) on 64-bit platforms.
Change the type of %pext32 to (bits32, bits32) -> bits32. (The corresponding Haskell function would be Word32# -> Word32# -> Word32#)
Change the implementation of hs_pext32 to return hs_pext64(src, (StgWord32)mask);.