diff options
author | Dimitrios Vytiniotis <dimitris@microsoft.com> | 2011-06-15 09:12:22 +0100 |
---|---|---|
committer | Dimitrios Vytiniotis <dimitris@microsoft.com> | 2011-06-15 09:12:22 +0100 |
commit | 8428e08f45952ae7c821e73b22557a88d65a8597 (patch) | |
tree | 0a8cc1890c39a35b8f6fffd7010f3c89ff577ccc /testsuite | |
parent | 48757c186402241273afff53d39beee1ede8a13a (diff) | |
parent | b23ecc8f0d419d1a261ac2d760528e804dacb470 (diff) | |
download | haskell-8428e08f45952ae7c821e73b22557a88d65a8597.tar.gz |
Merge branch 'master' of http://darcs.haskell.org/testsuite
Diffstat (limited to 'testsuite')
-rw-r--r-- | testsuite/driver/testlib.py | 4 | ||||
-rw-r--r-- | testsuite/tests/ghc-regress/codeGen/should_run/cgrun069.hs | 72 | ||||
-rw-r--r-- | testsuite/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm | 131 |
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); } |