On 30/03/2016 01:06, Reed Wilson wrote: > Hi list, > > I made a small function to demonstrate it: > let compare_str_sub p s s_off len = > if s_off < 0 || s_off + len > String.length s > then invalid_arg "Don't do that!"; > else p = s > ... > > The odd code is toward the beginning: (if (!= 3 1) (exit 2) (exit 3)) > I don't know a lot about cmm code, but it looks like something the > compiler should be able to optimize better. Fiddling with the flambda > optimization options doesn't seem to remove it. > > Is this just due to how new flambda is, or is there some other reason > that code makes it through? > > Thanks, > Reed Wlison This is some kind of code that was introduced by Cmmgen: Here is the clambda generated by flambda (if (if (< s_off_7/1208 0) 1 (let (Pintcomp_arg_15/1217 (string.length s_8/1209)) (> (+ s_off_7/1208 len_6/1207) Pintcomp_arg_15/1217))) (apply* camlPervasives__invalid_arg_279 "camlHop__apply_arg_31") (caml_string_equal p_9/1210 s_8/1209)) and the one without (if (|| (< s_off/1206 0) (> (+ s_off/1206 len/1207) (string.length s/1205))) (apply* camlPervasives__invalid_arg_1007 "camlHop__1"="Don't do that!") (caml_string_equal p/1204 s/1205))) )) You will notice this is almost identical, but that the '||' operator is in the 'if then else' form for the flambda version. This is due to the early conversion of '||' and '&&' to simplify things in the middle end. The downside being that some specific patterns recognized by the cmm generation are not recognized anymore (hence generating stupid stuff). There was a pull request to add a few patterns to cmmgen to handle that case, but some part where apparently lost in a merge conflict: https://github.com/ocaml/ocaml/pull/430/commits/355cf1d40b854711911ed332e9472cbd231ffc78 Thanks for the report ! For this kind of things, you should also open a ticket on mantis to keep track of it. I will soon open a PR to fix this. -- Pierre