RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1236615 - [ppc64le] Divide and mod operations fail to wrap around on 64 bit integers
Summary: [ppc64le] Divide and mod operations fail to wrap around on 64 bit integers
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: ocaml
Version: 7.3
Hardware: ppc64le
OS: Unspecified
unspecified
unspecified
Target Milestone: rc
: ---
Assignee: Richard W.M. Jones
QA Contact: Václav Kadlčík
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-06-29 14:40 UTC by Richard W.M. Jones
Modified: 2015-11-19 04:49 UTC (History)
3 users (show)

Fixed In Version: ocaml-4.01.0-22.6.el7
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-11-19 04:49:50 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
div.c (421 bytes, text/plain)
2015-06-29 15:07 UTC, Richard W.M. Jones
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2015:2185 0 normal SHIPPED_LIVE ocaml bug fix update 2015-11-19 08:07:24 UTC

Description Richard W.M. Jones 2015-06-29 14:40:16 UTC
Description of problem:

This error was found by running the test suite.  I have now enabled
the test suite (advisory only) in all Fedora builds, so we should
start seeing more of these kinds of detail problems.

Int64.rem (remainder) and Int64.div (divide) functions on 64 bit
integers do not work.

Save the following snippet of code as `test.ml':

------
open Printf
let () =
  let i = Int64.min_int in
  printf "i = Int64.min_int = %Ld\n" i;
  let j = Int64.of_int (-1) in
  printf "j = Int64.of_int -1 = %Ld\n" j;
  printf "Int64.rem i j = %Ld (expecting 0)\n" (Int64.rem i j);
  printf "Int64.div i j = %Ld (expecting min_int)\n" (Int64.div i j)
------

and compile it using:

ocamlopt.opt test.ml -o test

On x86-64 (no error):

$ ./test
i = Int64.min_int = -9223372036854775808
j = Int64.of_int -1 = -1
Int64.rem i j = 0 (expecting 0)
Int64.div i j = -9223372036854775808 (expecting min_int)

On ppc64le:

i = Int64.min_int = -9223372036854775808
j = Int64.of_int -1 = -1
Int64.rem i j = 9223372036854775807 (expecting 0)
Int64.div i j = -1 (expecting min_int)

Version-Release number of selected component (if applicable):

I'm actually testing this on Fedora, but since the Fedora and
RHEL ppc64le code generators are substantially identical, I
expect the same problem to happen there.

ocaml-4.01.0-24.fc21.ppc64le

It also happens with the fedora-ocaml repository which is where
we get Fedora and RHEL versions of OCaml from.
https://git.fedorahosted.org/git/fedora-ocaml.git

How reproducible:

100% - see above.

Comment 1 Richard W.M. Jones 2015-06-29 14:42:03 UTC
The bytecode compiler (ocamlc) works.

Comment 3 Richard W.M. Jones 2015-06-29 15:07:28 UTC
Created attachment 1044384 [details]
div.c

Attached is what I think would be an equivalent C program.

It gives the same results as the (x86-64) OCaml program when
I use gcc -O3:

$ gcc -O3 -Wall div.c -o div
$ ./div
i = INT64_MIN = -9223372036854775808
j = -1 = -1
rem i j = 0
div i j = -9223372036854775808

Strangely, on x86-64, with gcc -O0 I get this:

$ gcc -Wall div.c -o div
$ ./div
i = INT64_MIN = -9223372036854775808
j = -1 = -1
Floating point exception

On ppc64le, with gcc -O0, I get:

i = INT64_MIN = -9223372036854775808
j = -1 = -1
rem i j = 9223372036854775807
div i j = -1

Comment 4 Richard W.M. Jones 2015-06-29 16:27:38 UTC
Carlos O'Donell points on that the code in comment 3 invokes
signed integer overflow (in the division) and so the behaviour
is undefined.

Comment 5 Carlos O'Donell 2015-06-29 16:31:27 UTC
(In reply to Richard W.M. Jones from comment #4)
> Carlos O'Donell points on that the code in comment 3 invokes
> signed integer overflow (in the division) and so the behaviour
> is undefined.

The result of the division is "(-1)(INT64_MIN)" and is unrepresentable as a signed 64-bit two's compliment value. The signed integer overflow results in undefined behaviour both in the C program, and possibly in the Ocaml program (though there you would have to look at the language standard to see what it says). Even if Ocaml allowed it the result is unrepresentable in a type of the same width of storage e.g. 64-bits. The test case would be valid only if you used larger types e.g. 128-bits. The undefined behaviour allows the compiler to do anything it wants with the division and remainder operations, so you see a variety of results. It is my opinion that the highest quality result is that for x86_64 at -O0 which yields SIGFPE as it should since the result is unrepresentable.

The Ocaml test case is IMO likely invalid and should be fixed upstream.

Comment 6 Richard W.M. Jones 2015-06-29 16:42:00 UTC
The OCaml test is actually testing the wraparound case, because
int64 is supposed to wrap there.

Int64.min_int ÷ -1 -> Int64.max_int + 1 -> Int64.min_int
                                     wraparound

Comment 7 Richard W.M. Jones 2015-06-29 16:57:51 UTC
Extract from -dlambda output:

               (apply (field 1 (global Printf!))
                 [0:
                  [11:
                   "Int64.rem i j = "
                   [7: 0a 0a 0a [11: " (expecting 0)\n" 0a]]]
                  "Int64.rem i j = %Ld (expecting 0)\n"]
                 (Int64.mod i/1008 j/1009))
               (apply (field 1 (global Printf!))
                 [0:
                  [11:
                   "Int64.div i j = "
                   [7: 0a 0a 0a [11: " (expecting min_int)\n" 0a]]]
                  "Int64.div i j = %Ld (expecting min_int)\n"]
                 (Int64.div i/1008 j/1009)))))))

and from -dclambda output:

         (apply
           (apply* camlPrintf__fprintf_1025 
             (field 23 (global camlPervasives!))
             "camlTest__18"=block(0,"camlTest__16"=block(11,"camlTest__12"="Int64.rem i j = ","camlTest__15"=block(7,0a,0a,0a,"camlTest__14"=block(11,"camlTest__13"=" (expecting 0)\n",0a))),"camlTest__17"="Int64.rem i j = %Ld (expecting 0)\n"))
           "camlTest__19"=9223372036854775807L)
         (apply
           (apply* camlPrintf__fprintf_1025 
             (field 23 (global camlPervasives!))
             "camlTest__26"=block(0,"camlTest__24"=block(11,"camlTest__20"="Int64.div i j = ","camlTest__23"=block(7,0a,0a,0a,"camlTest__22"=block(11,"camlTest__21"=" (expecting min_int)\n",0a))),"camlTest__25"="Int64.div i j = %Ld (expecting min_int)\n"))
           "camlTest__7"=-1L)))

This shows that some kind of constant folding is happening
between these two stages.

Comment 8 Richard W.M. Jones 2015-06-29 18:17:13 UTC
Answer from upstream is to set:
let division_crashes_on_overflow = true                                         

See: https://groups.google.com/d/msg/ocaml-aggregation-list/WoT1x7q3EVY/6X5bjxgFv9YJ

Comment 9 Richard W.M. Jones 2015-06-29 20:54:03 UTC
This is a fix for the problem in Fedora:

https://git.fedorahosted.org/cgit/fedora-ocaml.git/patch/?id=cf026cf66315609afe8f76272e493259bade255f

I will leave this bug open because we need to fix it in RHEL too.

Comment 13 errata-xmlrpc 2015-11-19 04:49:50 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2015-2185.html


Note You need to log in before you can comment on or make changes to this bug.