The revision D105306 generalizes the sparse compiler support from “just” multiplication and addition to include subtraction (and negation by viewing -y as 0-y). Other than the subtlety that the disjunction needs to split x-y into x-y, x, and -y (rather than just y for addition), the generalization is straightforward.
For example, “x(i) = a(i) - b(i)” with a and b sparse becomes the usual while-loop with three cases followed by two for-loops, with the subtlety of using -b(i) in the third if-branch and second for-loop.
Next up is division, which is a very tricky operation, however, due to the fact that there is no clear cancelling property for zeros under the semantics of this operation for both floating-point and integer cases (e.g. you cannot simply assume 0/y is 0, since y may happen to be zero too, even when stored). The following table illustrates this issue (where the notation !x and x indicates an implicit zero and an explicit stored value, respectively).
x/y|!y | y |
---+---+---+
!x |0/0|0/y| FP: 0/0=NaN,c/0=Inf,0/c=0 with c true nonzero
x |x/0|x/y| INT: x/0=exception, with x any value
So, this probably means that the full iteration space must be traversed.
Any insights in how to handle this better?