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

Wrong code generation of e / e' and e mod e' with effectful e #7533

Closed
vicuna opened this Issue May 12, 2017 · 2 comments

Comments

Projects
None yet
2 participants
@vicuna
Copy link
Collaborator

vicuna commented May 12, 2017

Original bug ID: 7533
Reporter: jmi
Assigned to: @mshinwell
Status: resolved (set by @mshinwell on 2017-05-15T08:34:58Z)
Resolution: duplicate
Priority: normal
Severity: minor
Version: 4.04.1
Category: back end (clambda to assembly)
Related to: #7531
Monitored by: @yallop

Bug description

Consider the examples

(int_of_string "") / (let e = let w = false in () in 0)
(int_of_string "") / (List.hd [0])

At runtime the dividend throws an exception and the divisor evaluates to 0.
Under call-by-value, I expect the dividend to be evaluated before attempting a division. This agrees with the bytecode backend's output:

Fatal error: exception Failure("int_of_string")

However with the native code backend I get:

Fatal error: exception Division_by_zero

thereby removing the effect of the dividend.

I believe the problem is in asmcomp/cmmgen.ml, line 410-414,
when the divisor is sufficiently complex to not hit (or get constant folded to hit) the earlier cases:

| (c1, c2) ->
bind "divisor" c2 (fun c2 ->
Cifthenelse(c2,
Cop(Cdivi, [c1; c2], dbg),
raise_symbol dbg "caml_exn_Division_by_zero"))

Note how c1 never gets evaluated when we branch on the result of c2 and it is 0.

There is a similar problem with 'mod' (replacing '/' with 'mod' in the examples):

(int_of_string "") mod (let e = let w = false in () in 0)
(int_of_string "") mod (List.hd [0])

and the code generation case for mod in asmcomp/cmmgen.ml, line 446-450.

This is confirmed and reproducable on version 4.04.1 under Debian and 4.04.0 under OSX.

Note, these two issues are different from #7201 (fixed in #954) which concerned how the native code backend removed a Division_by_zero in the 0 / e and 0 mod e cases.

Steps to reproduce

$ echo '(int_of_string "") / (let e = let w = false in () in 0)' > div.ml
$ ocamlopt -o div.native div.ml
$ ocamlc -o div.byte div.ml
$ ./div.native
Fatal error: exception Division_by_zero
$ ./div.byte
Fatal error: exception Failure("int_of_string")

$ echo '(int_of_string "") mod (let e = let w = false in () in 0)' > mod.ml
$ ocamlopt -o mod.native mod.ml
$ ocamlc -o mod.byte mod.ml
$ ./mod.native
Fatal error: exception Division_by_zero
$ ./mod.byte
Fatal error: exception Failure("int_of_string")

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented May 15, 2017

Comment author: @mshinwell

Thanks for the report, I will look at this.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented May 15, 2017

Comment author: @mshinwell

Superceded by #1173

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.