This patch adds a simplification for floating point compares that
depend on the inversion of a variable. The comparison can be folded
such that it solely depends on the variable rather than the division.
E.g.:
foo(double x) { double a = 1.0 / x; if (a < 0) ... }
>
foo(double x) { double a = 1.0 / x; if (x < 0) ... }
The following conversion is applied if C!=0 where C is a compiler
known constant:
(C/x < 0) (C*x < 0) ... multiply by x*x; Note: x*x > 0 (see Remark 2) ... divide by C (x < 0) ... if C > 0 (x > 0) ... if C < 0
Remarks:
- To avoid cases where x = NaN only the ordered predicates (ogt, olt, oge, ole) are folded.
- The division requires the flag 'ninf' to be set. This also ensures there x!=0 can be assumed.
Assume x=0. We know C!=0 (by definition) and C!=inf ('ninf' is set). Therefore C/x=inf (IEEE754_2008.pdf 7.2 and 7.3). But, because 'ninf' is set, the compile can assume x!=0
- To avoid cases where C/x == 0.0, 'ninf' has to be set for the fdiv and fcmp instruction.
- To allow the multiplication by x*x 'arcp' and 'ninf' has to be set for the fdiv and fcmp instruction.