Author: David Schneider <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit