Dávid Bolvanský via llvm-dev
2018-May-23 23:48 UTC
[llvm-dev] Comparing results of math function calls
Hello, Code: int f1(int a, int b) { return sqrt(a) > sqrt(b); } int f2(int a, int b) { return a > b; } Possibly, under -ffast-math (to ignore NaNs), f1 could be transformed to f2 variant. Also a transformation could support sin and tan, and reverse comparison for cos. Suggestions? Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180524/042a317a/attachment.html>
Dávid Bolvanský via llvm-dev
2018-May-23 23:54 UTC
[llvm-dev] Comparing results of math function calls
+ Does LLVM marks values with an attribute like "value cannot be NaN/INFINITY"? 2018-05-24 1:48 GMT+02:00 Dávid Bolvanský <david.bolvansky at gmail.com>:> Hello, > > Code: > > int f1(int a, int b) { > return sqrt(a) > sqrt(b); > } > > int f2(int a, int b) { > return a > b; > } > > Possibly, under -ffast-math (to ignore NaNs), f1 could be transformed to > f2 variant. > > Also a transformation could support sin and tan, and reverse > comparison for cos. > > Suggestions? > > Thanks >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180524/e31cc837/attachment.html>
Fabian Giesen via llvm-dev
2018-May-24 00:33 UTC
[llvm-dev] Comparing results of math function calls
*Integer* a and b? What's the expected use case for this? For 32-bit integers feeding into a IEEE-754 double calc, this might work as long as a, b are known >= 0; for doubles/floats, this is not true, even excluding NaNs; take this counterexample (for float32) a = 1.0 - 0.5f*FLT_EPSILON // IEEE-754 float32: 0x3f7fffff b = 1.0 - 1.0f*FLT_EPSILON // IEEE-754 float32: 0x3f7ffffe sqrt(a) == sqrt(b) == a (in IEEE arithmetic, unless I messed up somewhere) therefore a>b but sa == sb [the equivalent example for doubles should also work] It's not true for 64-bit integers when the computation is done using IEEE doubles, because there are pairs of integers a, b such that a > b but (double)a == (double)b. As soon as rounding is involved, you _have_ to be prepared for strict inequalities turning into non-strict ones (at best). The equivalent non-strict inequality (a >= b implying sqrt(a) >= sqrt(b) provided all values are ordered) is somewhat less dicey and might actually work provided the values are known non-negative, but I'd want to see a (preferably mechanical) proof first. sin, cos, tan are all non-monotonic. After all, they're periodic! Before you can rewrite anything, even in ideal circumstances, you have to (at the very least) prove that all the operands in question are from an interval such that the restriction of sin (or cos, or tan) to said interval is monotonic. That's a _way_ stronger requirement than just "no NaNs". And that's assuming the library implementations of sin/cos/tan are such that they are monotonic when restricted to an appropriate interval. I don't believe that's guaranteed anywhere. (But I'd be happy to b corrected on that point.) -Fabian On 5/23/2018 4:48 PM, Dávid Bolvanský via llvm-dev wrote:> Hello, > > Code: > > int f1(int a, int b) { > return sqrt(a) > sqrt(b); > } > > int f2(int a, int b) { > return a > b; > } > > Possibly, under -ffast-math (to ignore NaNs), f1 could be transformed to > f2 variant. > > Also a transformation could support sin and tan, and reverse > comparison for cos. > > Suggestions? > > Thanks > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >