summaryrefslogtreecommitdiff
path: root/testsuite
diff options
context:
space:
mode:
authorDimitrios Vytiniotis <dimitris@microsoft.com>2011-06-15 09:12:22 +0100
committerDimitrios Vytiniotis <dimitris@microsoft.com>2011-06-15 09:12:22 +0100
commit8428e08f45952ae7c821e73b22557a88d65a8597 (patch)
tree0a8cc1890c39a35b8f6fffd7010f3c89ff577ccc /testsuite
parent48757c186402241273afff53d39beee1ede8a13a (diff)
parentb23ecc8f0d419d1a261ac2d760528e804dacb470 (diff)
downloadhaskell-8428e08f45952ae7c821e73b22557a88d65a8597.tar.gz
Merge branch 'master' of http://darcs.haskell.org/testsuite
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/driver/testlib.py4
-rw-r--r--testsuite/tests/ghc-regress/codeGen/should_run/cgrun069.hs72
-rw-r--r--testsuite/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm131
3 files changed, 196 insertions, 11 deletions
diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py
index 7909a6158e..e87f9bc503 100644
--- a/testsuite/driver/testlib.py
+++ b/testsuite/driver/testlib.py
@@ -770,8 +770,10 @@ def compile_and_run__( name, way, extra_hc_opts, top_mod, extra_mods ):
pretest_cleanup(name)
for mod in extra_mods:
- simple_build( mod, way, extra_hc_opts, 0, '', 0, 0 )
+ result = simple_build( mod, way, extra_hc_opts, 0, '', 0, 0 )
extra_hc_opts += " " + replace_suffix(mod, 'o')
+ if result == 'fail':
+ return result
if way == 'ghci': # interpreted...
return interpreter_run( name, way, extra_hc_opts, 0, top_mod )
diff --git a/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069.hs b/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069.hs
index d49e7f5100..0c6bf7afb0 100644
--- a/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069.hs
+++ b/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069.hs
@@ -5,11 +5,79 @@ import GHC.Exts
import Control.Exception
import System.IO
-foreign import prim "memintrinTest" memcpyTest :: Int# -> Int#
+foreign import prim "memintrinTest" basicTest :: Int# -> Int#
+
+foreign import prim "testMemset8_0" testMemset8_0 :: Int# -> Int#
+foreign import prim "testMemset8_8" testMemset8_8 :: Int# -> Int#
+foreign import prim "testMemset8_9" testMemset8_9 :: Int# -> Int#
+foreign import prim "testMemset8_10" testMemset8_10 :: Int# -> Int#
+foreign import prim "testMemset8_11" testMemset8_11 :: Int# -> Int#
+foreign import prim "testMemset8_12" testMemset8_12 :: Int# -> Int#
+foreign import prim "testMemset8_13" testMemset8_13 :: Int# -> Int#
+foreign import prim "testMemset8_14" testMemset8_14 :: Int# -> Int#
+foreign import prim "testMemset8_15" testMemset8_15 :: Int# -> Int#
+foreign import prim "testMemset8_16" testMemset8_16 :: Int# -> Int#
+foreign import prim "testMemset4_0" testMemset4_0 :: Int# -> Int#
+foreign import prim "testMemset4_4" testMemset4_4 :: Int# -> Int#
+foreign import prim "testMemset4_5" testMemset4_5 :: Int# -> Int#
+foreign import prim "testMemset4_6" testMemset4_6 :: Int# -> Int#
+foreign import prim "testMemset4_7" testMemset4_7 :: Int# -> Int#
+foreign import prim "testMemset4_8" testMemset4_8 :: Int# -> Int#
+
+foreign import prim "testMemcpy8_0" testMemcpy8_0 :: Int# -> Int#
+foreign import prim "testMemcpy8_8" testMemcpy8_8 :: Int# -> Int#
+foreign import prim "testMemcpy8_9" testMemcpy8_9 :: Int# -> Int#
+foreign import prim "testMemcpy8_10" testMemcpy8_10 :: Int# -> Int#
+foreign import prim "testMemcpy8_11" testMemcpy8_11 :: Int# -> Int#
+foreign import prim "testMemcpy8_12" testMemcpy8_12 :: Int# -> Int#
+foreign import prim "testMemcpy8_13" testMemcpy8_13 :: Int# -> Int#
+foreign import prim "testMemcpy8_14" testMemcpy8_14 :: Int# -> Int#
+foreign import prim "testMemcpy8_15" testMemcpy8_15 :: Int# -> Int#
+foreign import prim "testMemcpy8_16" testMemcpy8_16 :: Int# -> Int#
+foreign import prim "testMemcpy4_0" testMemcpy4_0 :: Int# -> Int#
+foreign import prim "testMemcpy4_4" testMemcpy4_4 :: Int# -> Int#
+foreign import prim "testMemcpy4_5" testMemcpy4_5 :: Int# -> Int#
+foreign import prim "testMemcpy4_6" testMemcpy4_6 :: Int# -> Int#
+foreign import prim "testMemcpy4_7" testMemcpy4_7 :: Int# -> Int#
+foreign import prim "testMemcpy4_8" testMemcpy4_8 :: Int# -> Int#
main = do
putStrLn "Mem{cpy,set,move} Intrinsics Test..."
- _ <- evaluate (I# (memcpyTest 1#))
+ _ <- evaluate (I# (basicTest 1#))
+
+ _ <- evaluate (I# (testMemset8_0 1#))
+ _ <- evaluate (I# (testMemset8_8 1#))
+ _ <- evaluate (I# (testMemset8_9 1#))
+ _ <- evaluate (I# (testMemset8_10 1#))
+ _ <- evaluate (I# (testMemset8_11 1#))
+ _ <- evaluate (I# (testMemset8_12 1#))
+ _ <- evaluate (I# (testMemset8_13 1#))
+ _ <- evaluate (I# (testMemset8_14 1#))
+ _ <- evaluate (I# (testMemset8_15 1#))
+ _ <- evaluate (I# (testMemset8_16 1#))
+ _ <- evaluate (I# (testMemset4_0 1#))
+ _ <- evaluate (I# (testMemset4_4 1#))
+ _ <- evaluate (I# (testMemset4_5 1#))
+ _ <- evaluate (I# (testMemset4_6 1#))
+ _ <- evaluate (I# (testMemset4_7 1#))
+ _ <- evaluate (I# (testMemset4_8 1#))
+
+ _ <- evaluate (I# (testMemcpy8_0 1#))
+ _ <- evaluate (I# (testMemcpy8_8 1#))
+ _ <- evaluate (I# (testMemcpy8_9 1#))
+ _ <- evaluate (I# (testMemcpy8_10 1#))
+ _ <- evaluate (I# (testMemcpy8_11 1#))
+ _ <- evaluate (I# (testMemcpy8_12 1#))
+ _ <- evaluate (I# (testMemcpy8_13 1#))
+ _ <- evaluate (I# (testMemcpy8_14 1#))
+ _ <- evaluate (I# (testMemcpy8_15 1#))
+ _ <- evaluate (I# (testMemcpy8_16 1#))
+ _ <- evaluate (I# (testMemcpy4_0 1#))
+ _ <- evaluate (I# (testMemcpy4_4 1#))
+ _ <- evaluate (I# (testMemcpy4_5 1#))
+ _ <- evaluate (I# (testMemcpy4_6 1#))
+ _ <- evaluate (I# (testMemcpy4_7 1#))
+ _ <- evaluate (I# (testMemcpy4_8 1#))
putStrLn "Test Passed!"
return ()
diff --git a/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm b/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm
index 2239697aa4..b2f563bbf6 100644
--- a/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm
+++ b/testsuite/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm
@@ -3,8 +3,10 @@
// Test that the Memcpy, Memmove, Memset GHC intrinsic functions
// are working correctly.
-section "rodata" { memsetErr : bits8[] "Memset Error Occured\n"; }
-section "rodata" { memcpyErr : bits8[] "Memcpy Error Occured\n"; }
+section "rodata" { memsetErr : bits8[] "Memset Error - align: %d size: %d\n"; }
+section "rodata" { memcpyErr : bits8[] "Memcpy Error - align: %d size: %d\n"; }
+// You have to call printf with the same number of args for every call.
+// This is as the LLVM backend doesn't support vararg functions.
section "rodata" { memmoveErr : bits8[] "Memmove Error Occured\n"; }
memintrinTest
@@ -35,14 +37,16 @@ while1:
}
if (bits8[src + off] != set8) {
- foreign "C" printf(memsetErr "ptr") [];
+ // call with two dummy args for LLVM's benefit.
+ // they'll be ignored by printf
+ foreign "C" printf(memsetErr "ptr", 0, 0) [];
goto while1_end;
}
off = off + 1;
goto while1;
-while1_end:
+while1_end:
// Test memcpy
prim %memcpy(dst "ptr", src "ptr", size, alignV) [];
@@ -55,14 +59,14 @@ while2:
}
if (bits8[dst + off] != set8) {
- foreign "C" printf(memcpyErr "ptr") [];
+ foreign "C" printf(memcpyErr "ptr", 0, 0) [];
goto while2_end;
}
off = off + 1;
goto while2;
-while2_end:
+while2_end:
// Test memove
set = 8;
@@ -82,14 +86,14 @@ while3:
}
if (bits8[src2 + off] != set8) {
- foreign "C" printf(memmoveErr "ptr") [];
+ foreign "C" printf(memmoveErr "ptr", 0, 0) [];
goto while3_end;
}
off = off + 1;
goto while3;
-while3_end:
+while3_end:
foreign "C" free(src);
foreign "C" free(dst);
@@ -97,3 +101,114 @@ while3_end:
jump %ENTRY_CODE(Sp(0));
}
+// ---------------------------------------------------------------------
+// Tests for unrolling
+
+// We generate code for each configuration of alignment and size rather
+// than looping over the possible alignments/sizes as the alignment and
+// size needs to be statically known for unrolling to happen.
+
+// Below we need both 'set' and 'set8' as memset takes a word for
+// historical reasons but really its a bits8. We check that setting
+// has ben done correctly at the bits8 level, so need bits8 version
+// for checking.
+#define TEST_MEMSET(ALIGN,SIZE) \
+ W_ size, src, dst, off, alignV, set; \
+ bits8 set8; \
+ set = 4; \
+ set8 = 4::bits8; \
+ size = SIZE; \
+ alignV = ALIGN; \
+ ("ptr" src) = foreign "C" malloc(size); \
+ ("ptr" dst) = foreign "C" malloc(size); \
+ prim %memset(src "ptr", set, size, alignV) []; \
+ off = 0; \
+loop: \
+ if (off == size) { \
+ goto loop_end; \
+ } \
+ if (bits8[src + off] != set8) { \
+ foreign "C" printf(memsetErr "ptr", ALIGN, SIZE) []; \
+ goto loop_end; \
+ } \
+ off = off + 1; \
+ goto loop; \
+loop_end: \
+ foreign "C" free(src); \
+ foreign "C" free(dst); \
+ jump %ENTRY_CODE(Sp(0));
+
+// This is not exactly beutiful but we need the separate functions to
+// avoid collisions between labels.
+//
+// The specific tests are selected with knowledge of the implementation
+// in mind in order to try to cover all branches and interesting corner
+// cases.
+
+testMemset8_0 { TEST_MEMSET(8,0); }
+testMemset8_8 { TEST_MEMSET(8,8); }
+testMemset8_9 { TEST_MEMSET(8,9); }
+testMemset8_10 { TEST_MEMSET(8,10); }
+testMemset8_11 { TEST_MEMSET(8,11); }
+testMemset8_12 { TEST_MEMSET(8,12); }
+testMemset8_13 { TEST_MEMSET(8,13); }
+testMemset8_14 { TEST_MEMSET(8,14); }
+testMemset8_15 { TEST_MEMSET(8,15); }
+testMemset8_16 { TEST_MEMSET(8,16); }
+
+testMemset4_0 { TEST_MEMSET(4,0); }
+testMemset4_4 { TEST_MEMSET(4,4); }
+testMemset4_5 { TEST_MEMSET(4,5); }
+testMemset4_6 { TEST_MEMSET(4,6); }
+testMemset4_7 { TEST_MEMSET(4,7); }
+testMemset4_8 { TEST_MEMSET(4,8); }
+
+#define TEST_MEMCPY(ALIGN,SIZE) \
+ W_ size, src, dst, off, alignV; \
+ size = SIZE; \
+ alignV = ALIGN; \
+ ("ptr" src) = foreign "C" malloc(size); \
+ ("ptr" dst) = foreign "C" malloc(size); \
+ off = 0; \
+init: \
+ if (off == size) { \
+ goto init_end; \
+ } \
+ bits8[src + off] = 0xaa; \
+ off = off + 1; \
+ goto init; \
+init_end: \
+ prim %memcpy(dst "ptr", src "ptr", size, alignV) []; \
+ off = 0; \
+loop: \
+ if (off == size) { \
+ goto loop_end; \
+ } \
+ if (bits8[dst + off] != bits8[src + off]) { \
+ foreign "C" printf(memcpyErr "ptr", ALIGN, SIZE) []; \
+ goto loop_end; \
+ } \
+ off = off + 1; \
+ goto loop; \
+loop_end: \
+ foreign "C" free(src); \
+ foreign "C" free(dst); \
+ jump %ENTRY_CODE(Sp(0));
+
+testMemcpy8_0 { TEST_MEMCPY(8,0); }
+testMemcpy8_8 { TEST_MEMCPY(8,8); }
+testMemcpy8_9 { TEST_MEMCPY(8,9); }
+testMemcpy8_10 { TEST_MEMCPY(8,10); }
+testMemcpy8_11 { TEST_MEMCPY(8,11); }
+testMemcpy8_12 { TEST_MEMCPY(8,12); }
+testMemcpy8_13 { TEST_MEMCPY(8,13); }
+testMemcpy8_14 { TEST_MEMCPY(8,14); }
+testMemcpy8_15 { TEST_MEMCPY(8,15); }
+testMemcpy8_16 { TEST_MEMCPY(8,16); }
+
+testMemcpy4_0 { TEST_MEMCPY(4,0); }
+testMemcpy4_4 { TEST_MEMCPY(4,4); }
+testMemcpy4_5 { TEST_MEMCPY(4,5); }
+testMemcpy4_6 { TEST_MEMCPY(4,6); }
+testMemcpy4_7 { TEST_MEMCPY(4,7); }
+testMemcpy4_8 { TEST_MEMCPY(4,8); }