[GHC] #12614: Integer division can overwrite other arguments to foreign call
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 (NCG) | Keywords: integer | Operating System: Unknown/Multiple division | Architecture: x86_64 | Type of failure: Incorrect result (amd64) | at runtime Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- If you call a foreign function, GHC can generate incorrect code while passing the arguments to the function, overwriting the 3rd argument if a later argument contains an integer division. Main.hs: {{{ {-# LANGUAGE ForeignFunctionInterface #-} module Main where {-# NOINLINE foo #-} foo :: Int -> IO () foo x = c_foo 0 0 x $ x + x `quot` 10 foreign import ccall "foo" c_foo :: Int -> Int -> Int -> Int -> IO () main :: IO () main = do foo 202 foo 203 foo 204 }}} foo.c: {{{ #include <stdio.h> void foo(int a, int b, int c, int d) { printf("%d, %d, %d, %d\n", a, b, c, d); } }}} Expected output: {{{ 0, 0, 202, 222 0, 0, 203, 223 0, 0, 204, 224 }}} Actual output: {{{ 0, 0, 2, 222 0, 0, 3, 223 0, 0, 4, 224 }}} The bug has to be somewhere in the code generator. The cmm reads: {{{ call "ccall" arg hints: [‘signed’, ‘signed’, ‘signed’, ‘signed’] result hints: [] foo(0, 0, _s3nE::I64, _s3nE::I64 + %MO_S_Quot_W64(_s3nE::I64, 10)); }}} This generates the following assembler code: {{{ xorl %edi,%edi xorl %esi,%esi movq %rbx,%rdx movl $10,%ecx movq %rax,%rdx <-- move 3rd argument into rdx movq %rbx,%rax movq %rdx,%r8 cqto idivq %rcx <-- rax := rax / rcx; rdx := rax % rcx movq %rbx,%rcx addq %rax,%rcx subq $8,%rsp xorl %eax,%eax movq %r8,%rbx call foo }}} Thus rdx is overwritten again before the call, leading to incorrect results. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler (NCG) | Version: 8.0.1 Resolution: | Keywords: integer | division Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by hsyl20): This looks very similar to #11792. Isn't the foreign call unsafe in your test case? -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler (NCG) | Version: 8.0.1 Resolution: | Keywords: integer | division Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by jscholl): You are right, it is most likely the same root cause. But no, the foreign call is not unsafe as far as I understand (the default is safe, right?). Also if I change it to an explicit safe or unsafe call the behavior is unchanged, so this does not seem to be a factor in this case. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler (NCG) | Version: 8.0.1 Resolution: | Keywords: integer | division Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by hsyl20): I have fixed both this issue and #11792 in Phab:D2263. I have added your failing example (extended to test pushed args) as a test too. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: patch Priority: high | Milestone: 8.0.2 Component: Compiler (NCG) | Version: 8.0.1 Resolution: | Keywords: integer | division Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #11792 | Differential Rev(s): Phab:D2263 Wiki Page: | -------------------------------------+------------------------------------- Changes (by hsyl20): * status: new => patch * cc: hsyl20 (added) * differential: => Phab:D2263 * related: => #11792 * priority: normal => high * milestone: => 8.0.2 -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: patch Priority: high | Milestone: 8.0.2 Component: Compiler (NCG) | Version: 8.0.1 Resolution: | Keywords: integer | division Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #11792 | Differential Rev(s): Phab:D2263 Wiki Page: | -------------------------------------+------------------------------------- Comment (by Ben Gamari <ben@…>): In [changeset:"b61b7c2462b919de7eb4c373e2e2145c6d78d04c/ghc" b61b7c24/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="b61b7c2462b919de7eb4c373e2e2145c6d78d04c" CodeGen X86: fix unsafe foreign calls wrt inlining Foreign calls (unsafe and safe) interact badly with inlining and register passing ABIs (see #11792 and #12614): the inlined code to compute a parameter of the call may overwrite a register already set to pass a preceding parameter. With this patch, we compute all parameters which are not simple expressions before assigning them to fixed registers required by the ABI. Test Plan: - Add test (test both reg and stack parameters) - Validate Reviewers: osa1, bgamari, austin, simonmar Reviewed By: simonmar Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2263 GHC Trac Issues: #11792, #12614 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: merge Priority: high | Milestone: 8.0.2 Component: Compiler (NCG) | Version: 8.0.1 Resolution: | Keywords: integer | division Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #11792 | Differential Rev(s): Phab:D2263 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: patch => merge -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#12614: Integer division can overwrite other arguments to foreign call -------------------------------------+------------------------------------- Reporter: jscholl | Owner: Type: bug | Status: closed Priority: high | Milestone: 8.0.2 Component: Compiler (NCG) | Version: 8.0.1 Resolution: fixed | Keywords: integer | division Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #11792 | Differential Rev(s): Phab:D2263 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: merge => closed * resolution: => fixed Comment: Comment:5 merged to `ghc-8.0` as aec4a514857d051f5eeb15b9cbc8e6dd29850c5f -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12614#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC