[pypy-svn] pypy default: Write (painfully) a randomized test that fails using two

arigo commits-noreply at bitbucket.org
Mon Mar 14 22:05:00 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r42648:abbf5aea041a
Date: 2011-03-14 16:35 -0400
http://bitbucket.org/pypy/pypy/changeset/abbf5aea041a/

Log:	Write (painfully) a randomized test that fails using two independent
	calls to remap_frame_layout().

diff --git a/pypy/jit/backend/x86/test/test_jump.py b/pypy/jit/backend/x86/test/test_jump.py
--- a/pypy/jit/backend/x86/test/test_jump.py
+++ b/pypy/jit/backend/x86/test/test_jump.py
@@ -1,3 +1,4 @@
+import random
 from pypy.jit.backend.x86.regloc import *
 from pypy.jit.backend.x86.regalloc import X86FrameManager
 from pypy.jit.backend.x86.jump import remap_frame_layout
@@ -142,3 +143,149 @@
                              ('push', s12),
                              ('mov', ebx, s12),
                              ('pop', ebx)]
+
+def test_random_mixed():
+    assembler = MockAssembler()
+    registers1 = [eax, ebx, ecx]
+    registers2 = [xmm0, xmm1, xmm2]
+    if IS_X86_32:
+        XMMWORDS = 2
+    elif IS_X86_64:
+        XMMWORDS = 1
+    #
+    def pick1():
+        n = random.randrange(-3, 10)
+        if n < 0:
+            return registers1[n]
+        else:
+            return frame_pos(n, INT)
+    def pick2():
+        n = random.randrange(-3 , 10 // XMMWORDS)
+        if n < 0:
+            return registers2[n]
+        else:
+            return frame_pos(n * XMMWORDS, FLOAT)
+    #
+    def pick1c():
+        n = random.randrange(-2000, 500)
+        if n >= 0:
+            return imm(n)
+        else:
+            return pick1()
+    #
+    def pick_dst(fn, count, seen):
+        result = []
+        while len(result) < count:
+            x = fn()
+            keys = [x._getregkey()]
+            if isinstance(x, StackLoc) and x.width > WORD:
+                keys.append(keys[0] + WORD)
+            for key in keys:
+                if key in seen:
+                    break
+            else:
+                for key in keys:
+                    seen[key] = True
+                result.append(x)
+        return result
+    #
+    def get_state(locations):
+        regs1 = {}
+        regs2 = {}
+        stack = {}
+        for i, loc in enumerate(locations):
+            if isinstance(loc, RegLoc):
+                if loc.is_xmm:
+                    if loc.width > WORD:
+                        newvalue = ('value-xmm-%d' % i,
+                                    'value-xmm-hiword-%d' % i)
+                    else:
+                        newvalue = 'value-xmm-%d' % i
+                    regs2[loc.value] = newvalue
+                else:
+                    regs1[loc.value] = 'value-int-%d' % i
+            elif isinstance(loc, StackLoc):
+                stack[loc.value] = 'value-width%d-%d' % (loc.width, i)
+                if loc.width > WORD:
+                    stack[loc.value+WORD] = 'value-hiword-%d' % i
+            else:
+                assert isinstance(loc, ImmedLoc)
+        return regs1, regs2, stack
+    #
+    for i in range(1000):
+        seen = {}
+        src_locations1 = [pick1c() for i in range(5)]
+        dst_locations1 = pick_dst(pick1, 5, seen)
+        src_locations2 = [pick2() for i in range(4)]
+        dst_locations2 = pick_dst(pick2, 4, seen)
+        assembler = MockAssembler()
+        #remap_frame_layout_mixed(assembler,
+        #                         src_locations1, dst_locations1, edi,
+        #                         src_locations2, dst_locations2, xmm7)
+        remap_frame_layout(assembler, src_locations1, dst_locations1, edi)
+        remap_frame_layout(assembler, src_locations2, dst_locations2, xmm7)
+        #
+        regs1, regs2, stack = get_state(src_locations1 +
+                                        src_locations2)
+        #
+        def read(loc, expected_width=None):
+            if expected_width is not None:
+                assert loc.width == expected_width
+            if isinstance(loc, RegLoc):
+                if loc.is_xmm:
+                    return regs2[loc.value]
+                else:
+                    return regs1[loc.value]
+            if isinstance(loc, StackLoc):
+                got = stack[loc.value]
+                if loc.width > WORD:
+                    got = (got, stack[loc.value+WORD])
+                return got
+            if isinstance(loc, ImmedLoc):
+                return 'const-%d' % loc.value
+            assert 0, loc
+        #
+        def write(loc, newvalue):
+            if isinstance(loc, RegLoc):
+                if loc.is_xmm:
+                    regs2[loc.value] = newvalue
+                else:
+                    regs1[loc.value] = newvalue
+            elif isinstance(loc, StackLoc):
+                if loc.width > WORD:
+                    newval1, newval2 = newvalue
+                    stack[loc.value] = newval1
+                    stack[loc.value+WORD] = newval2
+                else:
+                    stack[loc.value] = newvalue
+            else:
+                assert 0, loc
+        #
+        src_values1 = [read(loc, WORD) for loc in src_locations1]
+        src_values2 = [read(loc, 8)    for loc in src_locations2]
+        #
+        extrapushes = []
+        for op in assembler.ops:
+            if op[0] == 'mov':
+                src, dst = op[1:]
+                assert isinstance(src, (RegLoc, StackLoc, ImmedLoc))
+                assert isinstance(dst, (RegLoc, StackLoc))
+                assert not (isinstance(src, StackLoc) and
+                            isinstance(dst, StackLoc))
+                write(dst, read(src))
+            elif op[0] == 'push':
+                src, = op[1:]
+                assert isinstance(src, (RegLoc, StackLoc))
+                extrapushes.append(read(src))
+            elif op[0] == 'pop':
+                dst, = op[1:]
+                assert isinstance(dst, (RegLoc, StackLoc))
+                write(dst, extrapushes.pop())
+            else:
+                assert 0, "unknown op: %r" % (op,)
+        assert not extrapushes
+        #
+        for i, loc in enumerate(dst_locations1):
+            assert read(loc, WORD) == src_values1[i]
+        for i, loc in enumerate(dst_locations2):
+            assert read(loc, 8) == src_values2[i]


More information about the Pypy-commit mailing list