We've discussed this problem before in D70975. Copying directly from that description:
We check the number of uses as a predicate for whether some value is free to negate, but that use count can change as we rewrite the expression in getNegatedExpression(). So something that was marked free to negate during the cost evaluation phase becomes not free to negate during the rewrite phase (or the inverse - something that was not free becomes free). This can lead to a crash/assert because we expect that everything in an expression that is negatible to be handled in the corresponding code within getNegatedExpression().
The problem was similarly partly fixed in D75501, but we missed that the same behavior could originate from fmul/fdiv.
This is another incomplete fix for the whole problem, but I think that requires integrating getNegatibleCost() and getNegatedExpression(), so that we can't alter costs between analysis and rewrite.