[RFC] [i386] Test program for ms_abi to sysv_abi function calls

Daniel Santos daniel.santos@pobox.com
Fri Feb 3 23:30:00 GMT 2017


This is a test program designed to test 64-bit Microsoft ABI functions 
that call System V functions in a multitude of permutations to attempt 
to discover flaws in the generation of prologues and epilogues and the 
optimizationsand features that can affect them, specifically 
shrink-wrapping, sibling calls and DRAP.  This is an accompaniment to 
the below patch sets (and was instrumental in finding and fixingflaws!), 
but is not an ancestor.

Use aligned SSE movs for re-aligned MS ABI pro/epilogues - 
https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01859.html
Use out-of-line stubs for ms_abi pro/epilogues- (v3 to be posted 
shortly!  Old v2: https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02293.html)


Summary
=======

A C++ generator program (gen.cc) is built and run to generate an 
unguarded C header file, which is included by msabi.c.  This header 
defines a number of ms_abi functions that call sysv_abi functions with 
various conditions. The generator has a CLI for test selection and 
currently used arguments (in msabi.exp) generates about 19k tests.  The 
results of msabi.c and do_test.S are linked to create the test program.  
Build time for msabi.c is takes 200-ish seconds on an old Phenom, but 
execution is nearly instantaneous.

Each test function is called via an assembly stub (do_test_aligned or 
do_test_unaligned) that:

1. Saves non-volatile registers to a global buffer,
2. Fills non-volatile registers with random data,
3. Calls the test function,
4. Saves resulting non-volatile registers for later comparison, and
5. Restores non-volatile registers to original values.

Upon completion, the resulting register values are compared to the 
original random values to verify correctness.  The return value is also 
verified against what is expected to validate the correctness of both 
the generated code as well as the test its self.


What Is Tested
==============

The test permutations consists of:

A. A number of extra long parametersfor the function (0-5 being used now).
B. A mask of additional non-volatile registers to explicitly clobber 
(aside from RDI, RSI and XMM6-15, which are always clobbered):
   enum optional_regs
   {
     OPTIONAL_REG_RBX = 0x01,
     OPTIONAL_REG_RBP = 0x02,
     OPTIONAL_REG_R12 = 0x04,
     OPTIONAL_REG_R13 = 0x08,
     OPTIONAL_REG_R14 = 0x10,
     OPTIONAL_REG_R15 = 0x20,

     OPTIONAL_REG_ALL = 0x3f,
     OPTIONAL_REG_HFP_ALL = OPTIONAL_REG_ALL & (~OPTIONAL_REG_RBP)
   };

B. A collection of variants:
   enum fn_variants {
     FN_VAR_MSABI          = 0x01,/* This value is an implementation detail
                                      and NOT a test permutation. */
     FN_VAR_HFP            = 0x02,
     FN_VAR_REALIGN        = 0x04,
     FN_VAR_ALLOCA         = 0x08,
     FN_VAR_VARARGS        = 0x10,
     FN_VAR_SIBCALL        = 0x20,
     FN_VAR_SHRINK_WRAP    = 0x40,

     FN_VAR_HFP_OR_REALIGN = FN_VAR_HFP | FN_VAR_REALIGN,
     FN_VAR_MASK           = 0x7f,
     FN_VAR_COUNT          = 7
   };

The variants deserve a little more explanation.

* FN_VAR_MSABI       (implementation detail) Adds__attribute__((ms_abi)).
* FN_VAR_HFP         Adds 
__attribute__((optimize("no-omit-frame-pointer"))). FN_VAR_HFPand 
FN_VAR_REALIGNare mutually exclusive.
* FN_VAR_REALIGN Adds __attribute__((__force_align_arg_pointer__)).  The 
test will call this function twice -- with an aligned and misaligned stack.
* FN_VAR_ALLOCA      The ms_abi function calls alloca and passes the 
pointer to the sysv_abi function.
* FN_VAR_VARARGS     The ms_abi function takes varargs, but only passes 
the argptr to the sysv_abi function.
* FN_VAR_SIBCALL     The ms_abi function returns in a way that enables 
the sibling call optimization (skipped if FN_VAR_REALIGN | FN_VAR_HFP 
are enabled).
* FN_VAR_SHRINK_WRAP Tests a global variable and uses a branch that 
enables the use shrink wrapping.  Both the fast and slow path are tested.

The following nomenclature is used for function names:
(msabi|sysv)_<xx>_[r|f][a][v][s][w]<n>
  |            |    |    |  |  |  |  |
  |            |    |    |  |  |  | Number of extra parameters (longs)
  |            |    |    |  |  | shrink wrap
  |            |    |    |  |  sibling call
  |            |    |    |  varargs
  |            |    |    alloca
  |            |    Forced realignment or hard frame pointer
  |            Explicit clobbers (hexadecimalmask)
  Calling Convention


Examples
========

The function msabi_25_ra2looks like this:

__attribute__ ((noinline, ms_abi, __force_align_arg_pointer__))
long msabi_25_ra2 (long a, long b)
{
   void *alloca_mem;
   alloca_mem = alloca (8 + a);
   *(long*)alloca_mem = FLAG_ALLOCA;
   __asm__ __volatile__ ("" :::"rbx", "r12", "r15");
   return sysv_a2_noinfo (alloca_mem, a, b);
}


And the tests (both aligned and misaligned) looks something like this:

void init_test (void *fn, const char *name, enum alignment_option alignment,
                 enum shrink_wrap_option shrink_wrap, long ret_expected);
void do_tests ()
{
   long ret;

   long a = 1;
   long b = 2;

...

   init_test (msabi_25_ra2, "msabi_25_ra2", ALIGNMENT_ALIGNED, 
SHRINK_WRAP_NONE, a + b + FLAG_ALLOCA);
   ret = do_test_2 (a, b);
   check_results (ret);

   init_test (msabi_25_ra2, "msabi_25_ra2", ALIGNMENT_MISALIGNED, 
SHRINK_WRAP_NONE, a + b + FLAG_ALLOCA);
   __asm__ __volatile__ ("subq $8,%%rsp":::"cc");
   ret = do_test_u2 (a, b);
   __asm__ __volatile__ ("addq $8,%%rsp":::"cc");
   check_results (ret);
...
}

  gcc/Makefile.in                               |   2 +
  gcc/testsuite/gcc.target/i386/msabi/do_test.S | 162 ++++++
  gcc/testsuite/gcc.target/i386/msabi/gen.cc    | 788 
++++++++++++++++++++++++++
  gcc/testsuite/gcc.target/i386/msabi/msabi.c   | 379 +++++++++++++
  gcc/testsuite/gcc.target/i386/msabi/msabi.exp | 125 ++++
  5 files changed, 1456 insertions(+)

Daniel Santos

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-i386-Test-program-for-ms_abi-functions.patch
Type: text/x-patch
Size: 42166 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20170203/e020db4e/attachment.bin>


More information about the Gcc mailing list