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