Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove integer comparison involving nonconstant polymorphic variants #854

Merged
merged 1 commit into from
Oct 3, 2022

Conversation

lthls
Copy link
Contributor

@lthls lthls commented Sep 29, 2022

This hopefully means that we will be able to revert #729.

@mshinwell
Copy link
Collaborator

For context, this relates to examples like the following:

type simple = [ `Black | `Blue | `Red | `Green | `Yellow ]

let[@inline never] compare_simple s1 s2 = Sys.opaque_identity 0

type t = [ simple | `RGB of int ]

let compare t1 t2 =
  match t1, t2 with
  | #simple as s1, #simple as s2 -> compare_simple s1 s2
  | `RGB i1, `RGB i2 -> Int.compare i1 i2
  | x, y -> compare x y

let example = `RGB 12345

let compare_spec t = (compare [@inlined]) t example

where currently the pattern matching compiler is generating integer ordered comparisons between pointers and integers, which we wish to disallow:

(let
  (compare_simple/262 = (function s1/264 s2/265 never_inline : int (opaque 0))
   compare/335 =
     (function t1/336 t2/337 : int
       (catch
         (catch
           (if (isint t1/336)
             (if (>= t1/336 82908052) (if (!= t1/336 737308346) (if (!= t1/336 756711075) (if (>= t1/336 82908053) (exit 1) (exit 2)) (exit 2)) (exit 2))
               (if (!= t1/336 -937474657) (if (!= t1/336 4100401) (exit 1) (exit 2)) (exit 2)))
             (if (!= (field 0 t1/336) 4093677) (exit 1) (if (isint t2/337) (exit 1) (if (!= (field 0 t2/337) 4093677) (exit 1) (apply (field 8 (global Stdlib__Int!)) (field 1 t1/336) (field 1 t2/337))))))
          with (2)
           (catch
(* --> *)      (if (>= t2/337 82908052) (if (!= t2/337 737308346) (if (!= t2/337 756711075) (if (>= t2/337 82908053) (exit 1) (exit 3)) (exit 3)) (exit 3))
               (if (!= t2/337 -937474657) (if (!= t2/337 4100401) (exit 1) (exit 3)) (exit 3)))
            with (3) (apply compare_simple/262 t1/336 (makeblock 0 t1/336 t2/337))))
        with (1) (caml_compare t1/336 t2/337)))
   example/371 = [0: 4093677 12345]
   compare_spec/372 = (function t/374 : int (apply compare/335 t/374 example/371 always_inline)))
  (makeblock 0 compare_simple/262 compare/335 example/371 compare_spec/372))

@lthls
Copy link
Contributor Author

lthls commented Sep 30, 2022

I think this also fixes a bug.
Looking at the generated lambda:

(if (>= t1/336 82908052) ... (if (>= t1/336 82908053) ...

The last test checks whether t1/336 is equal to 82908052. It assumes the there is no valid input between 82908052 and 82908053. But after taking tagging into account, these become tests against 165816105 and 165816107 respectively. So there could be a pointer represented as 165816106 hiding in between (in this particular case, alignment forbids it, but it could happen for different hashes).
For this reason, I think we could upstream the fix.

@mshinwell
Copy link
Collaborator

Wow that is very subtle. We should upstream this.

@mshinwell mshinwell added the to upstream PR should be sent to upstream OCaml label Sep 30, 2022
@lthls
Copy link
Contributor Author

lthls commented Sep 30, 2022

I've created a PR upstream (ocaml/ocaml#11587).

@mshinwell
Copy link
Collaborator

I'm going to approve this based on the upstream approval.

@mshinwell mshinwell merged commit d77351a into ocaml-flambda:main Oct 3, 2022
mshinwell added a commit to mshinwell/flambda-backend that referenced this pull request Oct 24, 2022
25188da695 flambda-backend: Missed comment from PR802 (ocaml-flambda#887)
9469765e42 flambda-backend: Improve the semantics of asynchronous exceptions (new simpler version) (ocaml-flambda#802)
d9e4dd0c40 flambda-backend: Fix `make runtest` on NixOS (ocaml-flambda#874)
4bbde7a0f0 flambda-backend: Simpler symbols (ocaml-flambda#753)
ef37262ef1 flambda-backend: Add opaqueness to Obj.magic under Flambda 2 (ocaml-flambda#862)
a9616e98b1 flambda-backend: Add build system hooks for ocaml-jst (ocaml-flambda#869)
045ef67fdb flambda-backend: Allow the compiler to build with stock Dune (ocaml-flambda#868)
3cac5be480 flambda-backend: Simplify Makefile logic for natdynlinkops (ocaml-flambda#866)
c5b12bf362 flambda-backend: Remove unnecessary install lines (ocaml-flambda#860)
ff12bbe344 flambda-backend: Fix unused variable warning in st_stubs.c (ocaml-flambda#861)
c84976c1a2 flambda-backend: Static check for noalloc: attributes (ocaml-flambda#825)
ca56052e19 flambda-backend: Build system refactoring for ocaml-jst (ocaml-flambda#857)
39eb7f9b12 flambda-backend: Remove integer comparison involving nonconstant polymorphic variants (ocaml-flambda#854)
c102688f57 flambda-backend: Fix soundness bug by using currying information from typing (ocaml-flambda#850)
6a96b6142d flambda-backend: Add a primitive to enable/disable the tick thread (ocaml-flambda#852)
f64370bad9 flambda-backend: Make Obj.dup use a new primitive, %obj_dup (ocaml-flambda#843)
9b78eb2192 flambda-backend: Add test for ocaml-flambda#820 (include functor soundness bug) (ocaml-flambda#841)
8f24346583 flambda-backend: Add `-dtimings-precision` flag (ocaml-flambda#833)
65c2f22d33 flambda-backend: Add test for ocaml-flambda#829 (ocaml-flambda#831)
7b27a49334 flambda-backend: Follow-up PR#829 (comballoc fixes for locals) (ocaml-flambda#830)
ad7ec10060 flambda-backend: Use a custom condition variable implementation (ocaml-flambda#787)
3ee650c14d flambda-backend: Fix soundness bug in include functor (ocaml-flambda#820)
2f573789f3 flambda-backend: Static check noalloc (ocaml-flambda#778)
aaad625f4d flambda-backend: Emit begin/end region only when stack allocation is enabled (ocaml-flambda#812)
17c7173251 flambda-backend: Fix .cmt for included signatures (ocaml-flambda#803)
e11966990e flambda-backend: Increase delays in tests/lib-threads/beat.ml (ocaml-flambda#800)
ccc356dd43 flambda-backend: Prevent dynamic loading of the same .cmxs twice in private mode, etc. (ocaml-flambda#784)
14eb57247e flambda-backend: Make local extension point equivalent to local_ expression (ocaml-flambda#790)
487d11baee flambda-backend: Fix tast_iterator and tast_mapper for include functor. (ocaml-flambda#795)
a50a818fa0 flambda-backend: Reduce closure allocation in List (ocaml-flambda#792)
96c9c60d5f flambda-backend: Merge ocaml-jst
a775b88500 flambda-backend: Fix ocaml/otherlibs/unix 32-bit build (ocaml-flambda#767)
f7c2679d77 flambda-backend: Create object files internally to avoid invoking GAS (ocaml-flambda#757)
c7a46bb939 flambda-backend: Bugfix for Cmmgen.expr_size with locals (ocaml-flambda#756)
b337cb6015 flambda-backend: Fix build_upstream for PR749 (ocaml-flambda#750)
8e7e81c0ab flambda-backend: Differentiate is_int primitive between generic and variant-only versions (ocaml-flambda#749)

git-subtree-dir: ocaml
git-subtree-split: 25188da6951ae276e561923457fcfeb95b7ef392
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted upstream middle end to upstream PR should be sent to upstream OCaml
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants