One of the constant folding rules introduced in D2858 is:

(L y :-: v) :-: (L x :-: w) -> return $ mkL (y-x) `add` (w `add` v)

Or, after removing syntactic noise: `(y - v) - (x - w) ==> (y - x) + (w + v)`.

This is incorrect, since the sign of `v` is changed from negative to positive.

As a consequence, the following program prints `3` when compiled with `-O`:

-- This is just subtraction in disguise minus :: Int -> Int -> Int minus x y = (8 - y) - (8 - x) {-# NOINLINE minus #-} main :: IO () main = print (2 `minus` 1)

The correct rule is: `(y - v) - (x - w) ==> (y - x) + (w - v)`.

This commit does the fix. I haven't found any other issues with the constant

folding code, but it's difficult to be certain without some automated checking.