[pypy-svn] r75513 - pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test
jcreigh at codespeak.net
jcreigh at codespeak.net
Tue Jun 22 22:55:58 CEST 2010
Author: jcreigh
Date: Tue Jun 22 22:55:57 2010
New Revision: 75513
Modified:
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_runner.py
Log:
add test to catch case where a float comparision falls right on the edge of a MachineCodeBlock change
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_runner.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_runner.py Tue Jun 22 22:55:57 2010
@@ -2,7 +2,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr, rclass
from pypy.jit.metainterp.history import ResOperation, LoopToken
from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
- Box, BasicFailDescr)
+ Box, BoxFloat, BasicFailDescr)
from pypy.jit.backend.detect_cpu import getcpuclass
from pypy.jit.backend.x86.arch import WORD
from pypy.jit.backend.llsupport import symbolic
@@ -395,3 +395,59 @@
self.cpu.set_future_value_int(0, base_v.value)
self.cpu.execute_token(looptoken)
assert self.cpu.get_latest_value_int(0) == 1024
+
+ def test_overflow_guard_float_cmp(self):
+ # The float comparisons on x86 tend to use small relative jumps,
+ # which may run into trouble if they fall on the edge of a
+ # MachineCodeBlock change.
+ a = BoxFloat(1.0)
+ b = BoxFloat(2.0)
+ failed = BoxInt(41)
+ finished = BoxInt(42)
+
+ # We select guards that will always succeed, so that execution will
+ # continue through the entire set of comparisions
+ ops_to_test = (
+ (rop.FLOAT_LT, [a, b], rop.GUARD_TRUE),
+ (rop.FLOAT_LT, [b, a], rop.GUARD_FALSE),
+
+ (rop.FLOAT_LE, [a, a], rop.GUARD_TRUE),
+ (rop.FLOAT_LE, [a, b], rop.GUARD_TRUE),
+ (rop.FLOAT_LE, [b, a], rop.GUARD_FALSE),
+
+ (rop.FLOAT_EQ, [a, a], rop.GUARD_TRUE),
+ (rop.FLOAT_EQ, [a, b], rop.GUARD_FALSE),
+
+ (rop.FLOAT_NE, [a, b], rop.GUARD_TRUE),
+ (rop.FLOAT_NE, [a, a], rop.GUARD_FALSE),
+
+ (rop.FLOAT_GT, [b, a], rop.GUARD_TRUE),
+ (rop.FLOAT_GT, [a, b], rop.GUARD_FALSE),
+
+ (rop.FLOAT_GE, [a, a], rop.GUARD_TRUE),
+ (rop.FLOAT_GE, [b, a], rop.GUARD_TRUE),
+ (rop.FLOAT_GE, [a, b], rop.GUARD_FALSE),
+ )
+
+ for float_op, args, guard_op in ops_to_test:
+ ops = []
+
+ for i in range(200):
+ cmp_result = BoxInt()
+ ops.append(ResOperation(float_op, args, cmp_result))
+ ops.append(ResOperation(guard_op, [cmp_result], None, descr=BasicFailDescr()))
+ ops[-1].fail_args = [failed]
+
+ ops.append(ResOperation(rop.FINISH, [finished], None, descr=BasicFailDescr()))
+
+ looptoken = LoopToken()
+ self.cpu.compile_loop([a, b, failed, finished], ops, looptoken)
+ self.cpu.set_future_value_float(0, a.value)
+ self.cpu.set_future_value_float(1, b.value)
+ self.cpu.set_future_value_int(2, failed.value)
+ self.cpu.set_future_value_int(3, finished.value)
+ self.cpu.execute_token(looptoken)
+
+ # Really just a sanity check. We're actually interested in
+ # whether the test segfaults.
+ assert self.cpu.get_latest_value_int(0) == finished.value
More information about the Pypy-commit
mailing list