[pypy-commit] pypy default: A no-branch version of int_abs()

arigo noreply at buildbot.pypy.org
Tue Jul 16 10:33:34 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r65416:31e55d332904
Date: 2013-07-16 10:32 +0200
http://bitbucket.org/pypy/pypy/changeset/31e55d332904/

Log:	A no-branch version of int_abs()

diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -7,6 +7,7 @@
 from rpython.rlib import rgc
 from rpython.rlib.jit import elidable, oopspec
 from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask
+from rpython.rlib.rarithmetic import LONG_BIT
 from rpython.rtyper import rlist
 from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
 from rpython.rtyper.extregistry import ExtRegistryEntry
@@ -272,10 +273,9 @@
     return result
 
 def _ll_1_int_abs(x):
-    if x < 0:
-        return -x
-    else:
-        return x
+    # this version doesn't branch
+    mask = x >> (LONG_BIT - 1)
+    return (x ^ mask) - mask
 
 def _ll_1_cast_uint_to_float(x):
     # XXX on 32-bit platforms, this should be done using cast_longlong_to_float
diff --git a/rpython/jit/codewriter/test/test_support.py b/rpython/jit/codewriter/test/test_support.py
--- a/rpython/jit/codewriter/test/test_support.py
+++ b/rpython/jit/codewriter/test/test_support.py
@@ -1,8 +1,9 @@
-import py
+import py, sys
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.annlowlevel import llstr
 from rpython.flowspace.model import Variable, Constant, SpaceOperation
 from rpython.jit.codewriter.support import decode_builtin_call, LLtypeHelpers
+from rpython.jit.codewriter.support import _ll_1_int_abs
 
 def newconst(x):
     return Constant(x, lltype.typeOf(x))
@@ -133,3 +134,12 @@
     py.test.raises(IndexError, func, p1, llstr("w"))
     py.test.raises(AttributeError, func, p1, llstr(None))
     py.test.raises(AttributeError, func, llstr(None), p2)
+
+def test_int_abs():
+    assert _ll_1_int_abs(0) == 0
+    assert _ll_1_int_abs(1) == 1
+    assert _ll_1_int_abs(10) == 10
+    assert _ll_1_int_abs(sys.maxint) == sys.maxint
+    assert _ll_1_int_abs(-1) == 1
+    assert _ll_1_int_abs(-10) == 10
+    assert _ll_1_int_abs(-sys.maxint) == sys.maxint


More information about the pypy-commit mailing list