Closed meheff closed 11 months ago
Simplified a bit further, after cutting down params, taking the IR right before the actual invalid optimization, and then encouraging the minimizer to simplify the concat a bit with a bit of manual help... plus removing unneeded pos info and renumbering.
package sample
top fn __sample__main(x0: bits[2]) -> bits[1] {
literal.1: bits[1] = literal(value=1, id=1)
bit_slice.2: bits[1] = bit_slice(x0, start=0, width=1, id=2)
literal.3: bits[25] = literal(value=32508169, id=3)
concat.4: bits[27] = concat(literal.1, bit_slice.2, literal.3, id=4)
literal.5: bits[27] = literal(value=127305941, id=5)
ret sge.6: bits[1] = sge(concat.4, literal.5, id=6)
}
I've confirmed this was introduced in https://github.com/google/xls/commit/85249d232e5a93998d2de616eedd1c1d325b03b5
I understand the problem and have a fix incoming.
To summarize, signed comparisons with operands of the form 0XXXX can unconditionally be narrowed to unsigned comparisons with the MSB trimmed, but if the operands are of the form 1XXXX you can't. 10XXXX can be, though (flipping the order of the comparison). I'm adding a check that the next-most MSB is known 0.
This explanation was wrong, the real problem is that I shouldn't flip the operands. I mistakenly thought that dropping the MSB flipped the sign like multiplying by -1, but it's really just adding a fixed offset to both sides when you drop the MSB. This fixed offset doesn't change the direction of the comparison. The correct behavior is to drop MSBs in common and switch to unsigned comparisons. It's actually a lot simpler!
Found by the fuzzer. Minimized IR:
Repro: