diff options
author | Sylvain HENRY <hsyl20@gmail.com> | 2016-10-01 00:25:49 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-10-01 00:25:57 -0400 |
commit | b61b7c2462b919de7eb4c373e2e2145c6d78d04c (patch) | |
tree | 33f4566f33ba1c2582a2d423bcb5c26fe91398b2 /testsuite/tests/ffi | |
parent | 9e862765ffe161da8a4fd9cd67b0a600874feaa9 (diff) | |
download | haskell-b61b7c2462b919de7eb4c373e2e2145c6d78d04c.tar.gz |
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
Diffstat (limited to 'testsuite/tests/ffi')
-rw-r--r-- | testsuite/tests/ffi/should_run/T12614.hs | 22 | ||||
-rw-r--r-- | testsuite/tests/ffi/should_run/T12614.stdout | 6 | ||||
-rw-r--r-- | testsuite/tests/ffi/should_run/T12614_c.c | 5 | ||||
-rw-r--r-- | testsuite/tests/ffi/should_run/all.T | 5 |
4 files changed, 38 insertions, 0 deletions
diff --git a/testsuite/tests/ffi/should_run/T12614.hs b/testsuite/tests/ffi/should_run/T12614.hs new file mode 100644 index 0000000000..56ea3c124d --- /dev/null +++ b/testsuite/tests/ffi/should_run/T12614.hs @@ -0,0 +1,22 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +module Main where + +{-# NOINLINE test_reg #-} +test_reg :: Int -> IO () +test_reg x = c_foo 0 0 x (x + x `quot` 10) 0 0 0 0 + +{-# NOINLINE test_stack #-} +test_stack :: Int -> IO () +test_stack x = c_foo 0 0 x 0 0 0 (x + x `quot` 10) 0 + +foreign import ccall unsafe "foo" + c_foo :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> IO () + +main :: IO () +main = do + test_reg 202 + test_reg 203 + test_reg 204 + test_stack 202 + test_stack 203 + test_stack 204 diff --git a/testsuite/tests/ffi/should_run/T12614.stdout b/testsuite/tests/ffi/should_run/T12614.stdout new file mode 100644 index 0000000000..49315b03d7 --- /dev/null +++ b/testsuite/tests/ffi/should_run/T12614.stdout @@ -0,0 +1,6 @@ +0, 0, 202, 222, 0, 0, 0, 0 +0, 0, 203, 223, 0, 0, 0, 0 +0, 0, 204, 224, 0, 0, 0, 0 +0, 0, 202, 0, 0, 0, 222, 0 +0, 0, 203, 0, 0, 0, 223, 0 +0, 0, 204, 0, 0, 0, 224, 0 diff --git a/testsuite/tests/ffi/should_run/T12614_c.c b/testsuite/tests/ffi/should_run/T12614_c.c new file mode 100644 index 0000000000..8a8d5b136e --- /dev/null +++ b/testsuite/tests/ffi/should_run/T12614_c.c @@ -0,0 +1,5 @@ +#include <stdio.h> + +void foo(int a, int b, int c, int d, int e, int f, int g, int h) { + printf("%d, %d, %d, %d, %d, %d, %d, %d\n", a, b, c, d, e, f, g, h); +} diff --git a/testsuite/tests/ffi/should_run/all.T b/testsuite/tests/ffi/should_run/all.T index eb27564693..4e7417395d 100644 --- a/testsuite/tests/ffi/should_run/all.T +++ b/testsuite/tests/ffi/should_run/all.T @@ -218,3 +218,8 @@ test('T12134', compile_and_run, ['T12134_c.c']) +test('T12614', + [omit_ways(['ghci']), extra_clean(['T12614_c.o'])], + compile_and_run, + ['T12614_c.c']) + |