From c6f3a00b3105a5496783ac89d9213a5d866d5063 Mon Sep 17 00:00:00 2001 From: Leo White Date: Tue, 21 Nov 2017 17:38:18 +0000 Subject: [PATCH] Don't commute negation with float comparison (#1470) Floating-point comparisons such as `<` and `>=` are always false when one of their arguments is NaN. For this reason, it is incorrect to simplify `not (x < y)` as `x >= y` if this is a FP comparison. This wrong optimization was introduced in 4.06.0 and is being reverted by this commit. --- Changes | 3 +++ asmcomp/cmmgen.ml | 2 -- testsuite/tests/basic-float/float_compare.ml | 6 ++++++ testsuite/tests/basic-float/float_compare.reference | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 testsuite/tests/basic-float/float_compare.ml create mode 100644 testsuite/tests/basic-float/float_compare.reference diff --git a/Changes b/Changes index b8527ce2d..86b0703a1 100644 --- a/Changes +++ b/Changes @@ -80,6 +80,9 @@ Working version (Luc Maranget, review by Thomas Refis and Gabriel Scherer, report by Abdelraouf Ouadjaout and Thibault Suzanne) +- GPR#1470: Don't commute negation with float comparison + (Leo White, review by Xavier Leroy) + OCaml 4.06.0 (3 Nov 2017): -------------------------- diff --git a/asmcomp/cmmgen.ml b/asmcomp/cmmgen.ml index 079254d70..409ee7b3e 100644 --- a/asmcomp/cmmgen.ml +++ b/asmcomp/cmmgen.ml @@ -292,8 +292,6 @@ let mk_not dbg cmm = tag_int (Cop(Ccmpi (negate_comparison cmp), [c1; c2], dbg'')) dbg' | Cop(Ccmpa cmp, [c1; c2], dbg'') -> tag_int (Cop(Ccmpa (negate_comparison cmp), [c1; c2], dbg'')) dbg' - | Cop(Ccmpf cmp, [c1; c2], dbg'') -> - tag_int (Cop(Ccmpf (negate_comparison cmp), [c1; c2], dbg'')) dbg' | _ -> (* 0 -> 3, 1 -> 1 *) Cop(Csubi, [Cconst_int 3; Cop(Clsl, [c; Cconst_int 1], dbg)], dbg) diff --git a/testsuite/tests/basic-float/float_compare.ml b/testsuite/tests/basic-float/float_compare.ml new file mode 100644 index 000000000..d5b7a9a10 --- /dev/null +++ b/testsuite/tests/basic-float/float_compare.ml @@ -0,0 +1,6 @@ + +let compare_nan () = + not (nan < 0.0) +[@@inline never] + +let x = print_endline (string_of_bool (compare_nan ())) diff --git a/testsuite/tests/basic-float/float_compare.reference b/testsuite/tests/basic-float/float_compare.reference new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/testsuite/tests/basic-float/float_compare.reference @@ -0,0 +1 @@ +true