Author: David Schneider <david.schnei...@picle.org>
Branch: arm-backend-2
Changeset: r50210:63e21292fab4
Date: 2011-12-06 17:06 +0100
http://bitbucket.org/pypy/pypy/changeset/63e21292fab4/

Log:    (arigo, bivab): aahhh. Fix an issue with floats that are spilled in
        a loop and later read in a brigde. Due to an off by one issue the
        reading was broken in the bridge

diff --git a/pypy/jit/backend/arm/assembler.py 
b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -244,7 +244,7 @@
                 stack_loc = decode32(enc, i+1)
                 i += 4
                 if group == self.FLOAT_TYPE:
-                    value = decode64(stack, frame_depth - stack_loc*WORD)
+                    value = decode64(stack, frame_depth - (stack_loc+1)*WORD)
                     fvalue = rffi.cast(longlong.FLOATSTORAGE, value)
                     self.fail_boxes_float.setitem(fail_index, fvalue)
                     continue
@@ -408,7 +408,13 @@
                 else:
                     assert loc.is_stack()
                     mem[j] = self.STACK_LOC
-                    encode32(mem, j+1, loc.position)
+                    if arg.type == FLOAT:
+                        # Float locs store the location number with an offset
+                        # of 1 -.- so we need to take this into account here
+                        # when generating the encoding
+                        encode32(mem, j+1, loc.position-1)
+                    else:
+                        encode32(mem, j+1, loc.position)
                     j += 5
             else:
                 mem[j] = self.EMPTY_LOC
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -53,6 +53,9 @@
     def frame_pos(loc, type):
         num_words = ARMFrameManager.frame_size(type)
         if type == FLOAT:
+            # Make sure that loc is an even value
+            # the frame layout requires loc to be even!!
+            assert (loc & 1) == 0 
             return locations.StackLocation(loc+1, num_words=num_words, 
type=type)
         return locations.StackLocation(loc, num_words=num_words, type=type)
 
diff --git a/pypy/jit/backend/test/runner_test.py 
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -1212,6 +1212,51 @@
             got = longlong.getrealfloat(self.cpu.get_latest_value_float(i))
             assert got == 13.5 + 6.73 * i
 
+    def test_compile_bridge_spilled_float(self):
+        if not self.cpu.supports_floats:
+            py.test.skip("requires floats")
+        fboxes = [BoxFloat() for i in range(3)]
+        faildescr1 = BasicFailDescr(100)
+        loopops = """
+        [i0,f1, f2]
+        f3 = float_add(f1, f2)
+        force_spill(f3)
+        force_spill(f1)
+        force_spill(f2)
+        guard_false(i0) [f1, f2, f3]
+        finish()"""
+        loop = parse(loopops)
+        looptoken = LoopToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        self.cpu.set_future_value_int(0, 1)
+        self.cpu.set_future_value_float(1, longlong.getfloatstorage(132.25))
+        self.cpu.set_future_value_float(2, longlong.getfloatstorage(0.75))
+        fail = self.cpu.execute_token(looptoken)
+        assert loop.operations[-2].getdescr() == fail
+        f1 = self.cpu.get_latest_value_float(0)
+        f2 = self.cpu.get_latest_value_float(1)
+        f3 = self.cpu.get_latest_value_float(2)
+        assert longlong.getrealfloat(f1) == 132.25
+        assert longlong.getrealfloat(f2) == 0.75
+        assert longlong.getrealfloat(f3) == 133.0
+
+        bridgeops = [
+            ResOperation(rop.FINISH, fboxes, None, descr=faildescr1),
+            ]
+        self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes,
+                                                        bridgeops, looptoken)
+        self.cpu.set_future_value_int(0, 1)
+        self.cpu.set_future_value_float(1, longlong.getfloatstorage(132.25))
+        self.cpu.set_future_value_float(2, longlong.getfloatstorage(0.75))
+        fail = self.cpu.execute_token(looptoken)
+        assert fail.identifier == 100
+        f1 = self.cpu.get_latest_value_float(0)
+        f2 = self.cpu.get_latest_value_float(1)
+        f3 = self.cpu.get_latest_value_float(2)
+        assert longlong.getrealfloat(f1) == 132.25
+        assert longlong.getrealfloat(f2) == 0.75
+        assert longlong.getrealfloat(f3) == 133.0
+
     def test_integers_and_guards2(self):
         for opname, compare in [
             (rop.INT_IS_TRUE, lambda x: bool(x)),
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to