From 7e12a601b8e9d90e5a7498523a9023c8c47bc4ca Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 8 Oct 2015 13:02:00 +0100 Subject: [PATCH] py/compile: Fix edge case when constant-folding negation of integer. Also adds tests specifically for testing constant folding. --- py/compile.c | 5 +++- tests/basics/int_constfolding.py | 40 ++++++++++++++++++++++++++++++++ tests/basics/int_divmod.py | 6 ----- 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 tests/basics/int_constfolding.py diff --git a/py/compile.c b/py/compile.c index f9d53bc689..9d2a6f2af8 100644 --- a/py/compile.c +++ b/py/compile.c @@ -315,7 +315,10 @@ STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_m pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg); } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_MINUS)) { // -int - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, -arg); + arg = -arg; + if (MP_SMALL_INT_FITS(arg)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg); + } } else { assert(MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_TILDE)); // should be // ~int diff --git a/tests/basics/int_constfolding.py b/tests/basics/int_constfolding.py new file mode 100644 index 0000000000..c01f964daa --- /dev/null +++ b/tests/basics/int_constfolding.py @@ -0,0 +1,40 @@ +# tests int constant folding in compiler + +# positive +print(+1) +print(+100) + +# negation +print(-1) +print(-(-1)) +print(-0x3fffffff) # 32-bit edge case +print(-0x3fffffffffffffff) # 64-bit edge case +print(-(-0x3fffffff - 1)) # 32-bit edge case +print(-(-0x3fffffffffffffff - 1)) # 64-bit edge case + +# 1's complement +print(~0) +print(~1) +print(~-1) +print(~0x3fffffff) # 32-bit edge case +print(~0x3fffffffffffffff) # 64-bit edge case +print(~(-0x3fffffff - 1)) # 32-bit edge case +print(~(-0x3fffffffffffffff - 1)) # 64-bit edge case + +# addition +print(1 + 2) + +# subtraction +print(1 - 2) +print(2 - 1) + +# multiplication +print(1 * 2) +print(123 * 456) + +# floor div and modulo +print(123 // 7, 123 % 7) +print(-123 // 7, -123 % 7) +print(123 // -7, 123 % -7) +print(-123 // -7, -123 % -7) + diff --git a/tests/basics/int_divmod.py b/tests/basics/int_divmod.py index 71a990823e..3c76cd958c 100644 --- a/tests/basics/int_divmod.py +++ b/tests/basics/int_divmod.py @@ -6,12 +6,6 @@ for i in range(-2, 3): if j != 0: print(i, j, i // j, i % j, divmod(i, j)) -# this tests compiler constant folding -print(123 // 7, 123 % 7) -print(-123 // 7, -123 % 7) -print(123 // -7, 123 % -7) -print(-123 // -7, -123 % -7) - # this tests bignum modulo a = 987654321987987987987987987987 b = 19