diff --git a/backend/comballoc.ml b/backend/comballoc.ml index 3e78dd10acb..6040f651a2f 100644 --- a/backend/comballoc.ml +++ b/backend/comballoc.ml @@ -63,7 +63,8 @@ let rec combine i allocstate = i.arg i.res i.dbg next, allocstate) end | Iop(Icall_ind | Icall_imm _ | Iextcall _ | - Itailcall_ind | Itailcall_imm _ | Iprobe _) -> + Itailcall_ind | Itailcall_imm _ | Iprobe _ | + Iintop Icheckbound | Iintop_imm (Icheckbound, _)) -> let newnext = combine_restart i.next in (instr_cons_debug i.desc i.arg i.res i.dbg newnext, allocstate) diff --git a/backend/selectgen.ml b/backend/selectgen.ml index c11e0465c71..0319d283128 100644 --- a/backend/selectgen.ml +++ b/backend/selectgen.ml @@ -417,15 +417,16 @@ method is_simple_expr = function | Cextcall { effects = No_effects; coeffects = No_coeffects; } -> List.for_all self#is_simple_expr args (* The following may have side effects *) - | Capply _ | Cextcall _ | Calloc | Cstore _ | Craise _ | Cprobe _ - | Cprobe_is_enabled _ | Copaque -> false + | Capply _ | Cextcall _ | Calloc | Cstore _ + | Craise _ | Ccheckbound + | Cprobe _ | Cprobe_is_enabled _ | Copaque -> false | Cprefetch _ -> false (* avoid reordering *) (* The remaining operations are simple if their args are *) | Cload _ | Caddi | Csubi | Cmuli | Cmulhi _ | Cdivi | Cmodi | Cand | Cor | Cxor | Clsl | Clsr | Casr | Ccmpi _ | Caddv | Cadda | Ccmpa _ | Cnegf | Cclz _ | Cctz _ | Cpopcnt | Cabsf | Caddf | Csubf | Cmulf | Cdivf | Cfloatofint | Cintoffloat - | Ccmpf _ | Ccheckbound -> List.for_all self#is_simple_expr args + | Ccmpf _ -> List.for_all self#is_simple_expr args end | Cassign _ | Cifthenelse _ | Cswitch _ | Ccatch _ | Cexit _ | Ctrywith _ -> false diff --git a/ocaml/asmcomp/comballoc.ml b/ocaml/asmcomp/comballoc.ml index 1c9fba8f504..33b5e26ae51 100644 --- a/ocaml/asmcomp/comballoc.ml +++ b/ocaml/asmcomp/comballoc.ml @@ -63,7 +63,8 @@ let rec combine i allocstate = i.arg i.res i.dbg next, allocstate) end | Iop(Icall_ind | Icall_imm _ | Iextcall _ | - Itailcall_ind | Itailcall_imm _ | Iprobe _) -> + Itailcall_ind | Itailcall_imm _ | Iprobe _ | + Iintop Icheckbound | Iintop_imm (Icheckbound, _)) -> let newnext = combine_restart i.next in (instr_cons_debug i.desc i.arg i.res i.dbg newnext, allocstate) diff --git a/ocaml/asmcomp/selectgen.ml b/ocaml/asmcomp/selectgen.ml index c12dfc8b104..af11cd5f25d 100644 --- a/ocaml/asmcomp/selectgen.ml +++ b/ocaml/asmcomp/selectgen.ml @@ -324,13 +324,14 @@ method is_simple_expr = function | Cop(op, args, _) -> begin match op with (* The following may have side effects *) - | Capply _ | Cextcall _ | Calloc | Cstore _ | Craise _ | Cprobe _ - | Cprobe_is_enabled _ -> false + | Capply _ | Cextcall _ | Calloc | Cstore _ + | Craise _ | Ccheckbound + | Cprobe _ | Cprobe_is_enabled _ -> false (* The remaining operations are simple if their args are *) | Cload _ | Caddi | Csubi | Cmuli | Cmulhi | Cdivi | Cmodi | Cand | Cor | Cxor | Clsl | Clsr | Casr | Ccmpi _ | Caddv | Cadda | Ccmpa _ | Cnegf | Cabsf | Caddf | Csubf | Cmulf | Cdivf | Cfloatofint | Cintoffloat - | Ccmpf _ | Ccheckbound -> List.for_all self#is_simple_expr args + | Ccmpf _ -> List.for_all self#is_simple_expr args end | Cassign _ | Cifthenelse _ | Cswitch _ | Ccatch _ | Cexit _ | Ctrywith _ -> false diff --git a/ocaml/testsuite/tests/basic/combine_checkbound.ml b/ocaml/testsuite/tests/basic/combine_checkbound.ml new file mode 100644 index 00000000000..1bf096648a2 --- /dev/null +++ b/ocaml/testsuite/tests/basic/combine_checkbound.ml @@ -0,0 +1,36 @@ +(* TEST + * native *) + +let glob = ref (1, 2) +let[@inline never] combine1 x a = + begin try + glob := (2, x); + glob := (3, a.(4)); + with + | Invalid_argument _ -> () + end; + !glob + +let[@inline never] combine2 x a = + let loc = ref (1, 2) in + begin try + loc := (2, x); + loc := (3, a.(4)); + with + | Invalid_argument _ -> () + end; + !loc + +let[@inline never] measure f = + let empty_array = [| |] in + let prebefore = Gc.minor_words () in + let before = Gc.minor_words () in + let r = f 42 empty_array in + assert (r = (2, 42)); + let after = Gc.minor_words () in + ((after -. before) -. (before -. prebefore)) + + +let () = + Printf.printf "%10s: %.0f\n" "combine1" (measure combine1); + Printf.printf "%10s: %.0f\n" "combine2" (measure combine2) diff --git a/ocaml/testsuite/tests/basic/combine_checkbound.reference b/ocaml/testsuite/tests/basic/combine_checkbound.reference new file mode 100644 index 00000000000..e610ebd0790 --- /dev/null +++ b/ocaml/testsuite/tests/basic/combine_checkbound.reference @@ -0,0 +1,2 @@ + combine1: 3 + combine2: 3