Ticket #5208: 0001-Add-test-for-unrolling-memcpy-memset-in-the-x86-back.patch

File 0001-Add-test-for-unrolling-memcpy-memset-in-the-x86-back.patch, 11.7 KB (added by tibbe, 2 years ago)
  • tests/ghc-regress/codeGen/should_run/cgrun069.hs

    From 2fa63c3d2f55f1519410deafb3dec2620643d292 Mon Sep 17 00:00:00 2001
    From: Johan Tibell <johan.tibell@gmail.com>
    Date: Wed, 8 Jun 2011 17:27:59 +0200
    Subject: [PATCH] Add test for unrolling memcpy/memset in the x86 backend
    
    ---
     tests/ghc-regress/codeGen/should_run/cgrun069.hs   |   72 +++++++++++-
     .../codeGen/should_run/cgrun069_cmm.cmm            |  121 +++++++++++++++++++-
     2 files changed, 186 insertions(+), 7 deletions(-)
    
    diff --git a/tests/ghc-regress/codeGen/should_run/cgrun069.hs b/tests/ghc-regress/codeGen/should_run/cgrun069.hs
    index d49e7f5..0c6bf7a 100644
    a b  
    55import Control.Exception 
    66import System.IO 
    77 
    8 foreign import prim "memintrinTest" memcpyTest :: Int# -> Int# 
     8foreign import prim "memintrinTest" basicTest :: Int# -> Int# 
     9 
     10foreign import prim "testMemset8_0" testMemset8_0 :: Int# -> Int# 
     11foreign import prim "testMemset8_8" testMemset8_8 :: Int# -> Int# 
     12foreign import prim "testMemset8_9" testMemset8_9 :: Int# -> Int# 
     13foreign import prim "testMemset8_10" testMemset8_10 :: Int# -> Int# 
     14foreign import prim "testMemset8_11" testMemset8_11 :: Int# -> Int# 
     15foreign import prim "testMemset8_12" testMemset8_12 :: Int# -> Int# 
     16foreign import prim "testMemset8_13" testMemset8_13 :: Int# -> Int# 
     17foreign import prim "testMemset8_14" testMemset8_14 :: Int# -> Int# 
     18foreign import prim "testMemset8_15" testMemset8_15 :: Int# -> Int# 
     19foreign import prim "testMemset8_16" testMemset8_16 :: Int# -> Int# 
     20foreign import prim "testMemset4_0" testMemset4_0 :: Int# -> Int# 
     21foreign import prim "testMemset4_4" testMemset4_4 :: Int# -> Int# 
     22foreign import prim "testMemset4_5" testMemset4_5 :: Int# -> Int# 
     23foreign import prim "testMemset4_6" testMemset4_6 :: Int# -> Int# 
     24foreign import prim "testMemset4_7" testMemset4_7 :: Int# -> Int# 
     25foreign import prim "testMemset4_8" testMemset4_8 :: Int# -> Int# 
     26 
     27foreign import prim "testMemcpy8_0" testMemcpy8_0 :: Int# -> Int# 
     28foreign import prim "testMemcpy8_8" testMemcpy8_8 :: Int# -> Int# 
     29foreign import prim "testMemcpy8_9" testMemcpy8_9 :: Int# -> Int# 
     30foreign import prim "testMemcpy8_10" testMemcpy8_10 :: Int# -> Int# 
     31foreign import prim "testMemcpy8_11" testMemcpy8_11 :: Int# -> Int# 
     32foreign import prim "testMemcpy8_12" testMemcpy8_12 :: Int# -> Int# 
     33foreign import prim "testMemcpy8_13" testMemcpy8_13 :: Int# -> Int# 
     34foreign import prim "testMemcpy8_14" testMemcpy8_14 :: Int# -> Int# 
     35foreign import prim "testMemcpy8_15" testMemcpy8_15 :: Int# -> Int# 
     36foreign import prim "testMemcpy8_16" testMemcpy8_16 :: Int# -> Int# 
     37foreign import prim "testMemcpy4_0" testMemcpy4_0 :: Int# -> Int# 
     38foreign import prim "testMemcpy4_4" testMemcpy4_4 :: Int# -> Int# 
     39foreign import prim "testMemcpy4_5" testMemcpy4_5 :: Int# -> Int# 
     40foreign import prim "testMemcpy4_6" testMemcpy4_6 :: Int# -> Int# 
     41foreign import prim "testMemcpy4_7" testMemcpy4_7 :: Int# -> Int# 
     42foreign import prim "testMemcpy4_8" testMemcpy4_8 :: Int# -> Int# 
    943 
    1044main = do 
    1145    putStrLn "Mem{cpy,set,move} Intrinsics Test..." 
    12     _ <- evaluate (I# (memcpyTest 1#)) 
     46    _ <- evaluate (I# (basicTest 1#)) 
     47     
     48    _ <- evaluate (I# (testMemset8_0 1#)) 
     49    _ <- evaluate (I# (testMemset8_8 1#)) 
     50    _ <- evaluate (I# (testMemset8_9 1#)) 
     51    _ <- evaluate (I# (testMemset8_10 1#)) 
     52    _ <- evaluate (I# (testMemset8_11 1#)) 
     53    _ <- evaluate (I# (testMemset8_12 1#)) 
     54    _ <- evaluate (I# (testMemset8_13 1#)) 
     55    _ <- evaluate (I# (testMemset8_14 1#)) 
     56    _ <- evaluate (I# (testMemset8_15 1#)) 
     57    _ <- evaluate (I# (testMemset8_16 1#)) 
     58    _ <- evaluate (I# (testMemset4_0 1#)) 
     59    _ <- evaluate (I# (testMemset4_4 1#)) 
     60    _ <- evaluate (I# (testMemset4_5 1#)) 
     61    _ <- evaluate (I# (testMemset4_6 1#)) 
     62    _ <- evaluate (I# (testMemset4_7 1#)) 
     63    _ <- evaluate (I# (testMemset4_8 1#)) 
     64     
     65    _ <- evaluate (I# (testMemcpy8_0 1#)) 
     66    _ <- evaluate (I# (testMemcpy8_8 1#)) 
     67    _ <- evaluate (I# (testMemcpy8_9 1#)) 
     68    _ <- evaluate (I# (testMemcpy8_10 1#)) 
     69    _ <- evaluate (I# (testMemcpy8_11 1#)) 
     70    _ <- evaluate (I# (testMemcpy8_12 1#)) 
     71    _ <- evaluate (I# (testMemcpy8_13 1#)) 
     72    _ <- evaluate (I# (testMemcpy8_14 1#)) 
     73    _ <- evaluate (I# (testMemcpy8_15 1#)) 
     74    _ <- evaluate (I# (testMemcpy8_16 1#)) 
     75    _ <- evaluate (I# (testMemcpy4_0 1#)) 
     76    _ <- evaluate (I# (testMemcpy4_4 1#)) 
     77    _ <- evaluate (I# (testMemcpy4_5 1#)) 
     78    _ <- evaluate (I# (testMemcpy4_6 1#)) 
     79    _ <- evaluate (I# (testMemcpy4_7 1#)) 
     80    _ <- evaluate (I# (testMemcpy4_8 1#)) 
    1381    putStrLn "Test Passed!" 
    1482    return () 
    1583 
  • tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm

    diff --git a/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm b/tests/ghc-regress/codeGen/should_run/cgrun069_cmm.cmm
    index 2239697..9953181 100644
    a b  
    33// Test that the Memcpy, Memmove, Memset GHC intrinsic functions 
    44// are working correctly. 
    55 
    6 section "rodata" { memsetErr : bits8[] "Memset Error Occured\n"; } 
    7 section "rodata" { memcpyErr : bits8[] "Memcpy Error Occured\n"; } 
     6section "rodata" { memsetErr : bits8[] "Memset Error - align: %d size: %d\n"; } 
     7section "rodata" { memcpyErr : bits8[] "Memcpy Error - align: %d size: %d\n"; } 
    88section "rodata" { memmoveErr : bits8[] "Memmove Error Occured\n"; } 
    99 
    1010memintrinTest 
     
    4242                off = off + 1; 
    4343                goto while1; 
    4444 
    45 while1_end:  
     45while1_end: 
    4646 
    4747   // Test memcpy 
    4848        prim %memcpy(dst "ptr", src "ptr", size, alignV) []; 
     
    6262                off = off + 1; 
    6363                goto while2; 
    6464 
    65 while2_end:  
     65while2_end: 
    6666 
    6767   // Test memove 
    6868        set = 8; 
     
    8989                off = off + 1; 
    9090                goto while3; 
    9191 
    92 while3_end:  
     92while3_end: 
    9393 
    9494        foreign "C" free(src); 
    9595        foreign "C" free(dst); 
     
    9797        jump %ENTRY_CODE(Sp(0)); 
    9898} 
    9999 
     100// --------------------------------------------------------------------- 
     101// Tests for unrolling 
     102 
     103// We generate code for each configuration of alignment and size rather 
     104// than looping over the possible alignments/sizes as the alignment and 
     105// size needs to be statically known for unrolling to happen. 
     106 
     107// Below we need both 'set' and 'set8' as memset takes a word for 
     108// historical reasons but really its a bits8. We check that setting 
     109// has ben done correctly at the bits8 level, so need bits8 version 
     110// for checking. 
     111#define TEST_MEMSET(ALIGN,SIZE)                                        \ 
     112    W_ size, src, dst, off, alignV, set;                               \ 
     113    bits8 set8;                                                        \ 
     114    set = 4;                                                           \ 
     115    set8 = 4::bits8;                                                   \ 
     116    size = SIZE;                                                       \ 
     117    alignV = ALIGN;                                                    \ 
     118    ("ptr" src) = foreign "C" malloc(size);                            \ 
     119    ("ptr" dst) = foreign "C" malloc(size);                            \ 
     120    prim %memset(src "ptr", set, size, alignV) [];                     \ 
     121    off = 0;                                                           \ 
     122loop:                                                                  \ 
     123    if (off == size) {                                                 \ 
     124        goto loop_end;                                                 \ 
     125    }                                                                  \ 
     126    if (bits8[src + off] != set8) {                                    \ 
     127        foreign "C" printf(memsetErr "ptr", ALIGN, SIZE) [];           \ 
     128        goto loop_end;                                                 \ 
     129    }                                                                  \ 
     130    off = off + 1;                                                     \ 
     131    goto loop;                                                         \ 
     132loop_end:                                                              \ 
     133    foreign "C" free(src);                                             \ 
     134    foreign "C" free(dst);                                             \ 
     135    jump %ENTRY_CODE(Sp(0)); 
     136 
     137// This is not exactly beutiful but we need the separate functions to 
     138// avoid collisions between labels. 
     139// 
     140// The specific tests are selected with knowledge of the implementation 
     141// in mind in order to try to cover all branches and interesting corner 
     142// cases. 
     143 
     144testMemset8_0 { TEST_MEMSET(8,0); } 
     145testMemset8_8 { TEST_MEMSET(8,8); } 
     146testMemset8_9 { TEST_MEMSET(8,9); } 
     147testMemset8_10 { TEST_MEMSET(8,10); } 
     148testMemset8_11 { TEST_MEMSET(8,11); } 
     149testMemset8_12 { TEST_MEMSET(8,12); } 
     150testMemset8_13 { TEST_MEMSET(8,13); } 
     151testMemset8_14 { TEST_MEMSET(8,14); } 
     152testMemset8_15 { TEST_MEMSET(8,15); } 
     153testMemset8_16 { TEST_MEMSET(8,16); } 
     154 
     155testMemset4_0 { TEST_MEMSET(4,0); } 
     156testMemset4_4 { TEST_MEMSET(4,4); } 
     157testMemset4_5 { TEST_MEMSET(4,5); } 
     158testMemset4_6 { TEST_MEMSET(4,6); } 
     159testMemset4_7 { TEST_MEMSET(4,7); } 
     160testMemset4_8 { TEST_MEMSET(4,8); } 
     161 
     162#define TEST_MEMCPY(ALIGN,SIZE)                                        \ 
     163    W_ size, src, dst, off, alignV;                                    \ 
     164    size = SIZE;                                                       \ 
     165    alignV = ALIGN;                                                    \ 
     166    ("ptr" src) = foreign "C" malloc(size);                            \ 
     167    ("ptr" dst) = foreign "C" malloc(size);                            \ 
     168    off = 0;                                                           \ 
     169init:                                                                  \ 
     170    if (off == size) {                                                 \ 
     171        goto init_end;                                                 \ 
     172    }                                                                  \ 
     173    bits8[src + off] = 0xaa;                                           \ 
     174    off = off + 1;                                                     \ 
     175    goto init;                                                         \ 
     176init_end:                                                              \ 
     177    prim %memcpy(dst "ptr", src "ptr", size, alignV) [];               \ 
     178    off = 0;                                                           \ 
     179loop:                                                                  \ 
     180    if (off == size) {                                                 \ 
     181        goto loop_end;                                                 \ 
     182    }                                                                  \ 
     183    if (bits8[dst + off] != bits8[src + off]) {                        \ 
     184        foreign "C" printf(memcpyErr "ptr", ALIGN, SIZE) [];           \ 
     185        goto loop_end;                                                 \ 
     186    }                                                                  \ 
     187    off = off + 1;                                                     \ 
     188    goto loop;                                                         \ 
     189loop_end:                                                              \ 
     190   foreign "C" free(src);                                              \ 
     191   foreign "C" free(dst);                                              \ 
     192   jump %ENTRY_CODE(Sp(0)); 
     193 
     194testMemcpy8_0 { TEST_MEMCPY(8,0); } 
     195testMemcpy8_8 { TEST_MEMCPY(8,8); } 
     196testMemcpy8_9 { TEST_MEMCPY(8,9); } 
     197testMemcpy8_10 { TEST_MEMCPY(8,10); } 
     198testMemcpy8_11 { TEST_MEMCPY(8,11); } 
     199testMemcpy8_12 { TEST_MEMCPY(8,12); } 
     200testMemcpy8_13 { TEST_MEMCPY(8,13); } 
     201testMemcpy8_14 { TEST_MEMCPY(8,14); } 
     202testMemcpy8_15 { TEST_MEMCPY(8,15); } 
     203testMemcpy8_16 { TEST_MEMCPY(8,16); } 
     204 
     205testMemcpy4_0 { TEST_MEMCPY(4,0); } 
     206testMemcpy4_4 { TEST_MEMCPY(4,4); } 
     207testMemcpy4_5 { TEST_MEMCPY(4,5); } 
     208testMemcpy4_6 { TEST_MEMCPY(4,6); } 
     209testMemcpy4_7 { TEST_MEMCPY(4,7); } 
     210testMemcpy4_8 { TEST_MEMCPY(4,8); }