summaryrefslogtreecommitdiff
path: root/testsuite/tests/ffi
diff options
context:
space:
mode:
authorSylvain HENRY <hsyl20@gmail.com>2016-10-01 00:25:49 -0400
committerBen Gamari <ben@smart-cactus.org>2016-10-01 00:25:57 -0400
commitb61b7c2462b919de7eb4c373e2e2145c6d78d04c (patch)
tree33f4566f33ba1c2582a2d423bcb5c26fe91398b2 /testsuite/tests/ffi
parent9e862765ffe161da8a4fd9cd67b0a600874feaa9 (diff)
downloadhaskell-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.hs22
-rw-r--r--testsuite/tests/ffi/should_run/T12614.stdout6
-rw-r--r--testsuite/tests/ffi/should_run/T12614_c.c5
-rw-r--r--testsuite/tests/ffi/should_run/all.T5
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'])
+