diff --git a/mypyc/ir/pprint.py b/mypyc/ir/pprint.py index 8d6723917ea0..2ca6a47921fc 100644 --- a/mypyc/ir/pprint.py +++ b/mypyc/ir/pprint.py @@ -232,7 +232,7 @@ def visit_primitive_op(self, op: PrimitiveOp) -> str: type_arg_index += 1 args_str = ", ".join(args) - return self.format("%r = %s %s ", op, op.desc.name, args_str) + return self.format("%r = %s %s", op, op.desc.name, args_str) def visit_truncate(self, op: Truncate) -> str: return self.format("%r = truncate %r: %t to %t", op, op.src, op.src_type, op.type) diff --git a/mypyc/irbuild/ast_helpers.py b/mypyc/irbuild/ast_helpers.py index 8490eaa03477..bc976647675d 100644 --- a/mypyc/irbuild/ast_helpers.py +++ b/mypyc/irbuild/ast_helpers.py @@ -93,12 +93,9 @@ def maybe_process_conditional_comparison( self.add_bool_branch(reg, true, false) else: # "left op right" for two tagged integers - if op in ("==", "!="): - reg = self.builder.binary_op(left, right, op, e.line) - self.flush_keep_alives() - self.add_bool_branch(reg, true, false) - else: - self.builder.compare_tagged_condition(left, right, op, true, false, e.line) + reg = self.builder.binary_op(left, right, op, e.line) + self.flush_keep_alives() + self.add_bool_branch(reg, true, false) return True diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 52891d68e3b2..cca771e82c83 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -378,9 +378,6 @@ def call_c(self, desc: CFunctionDescription, args: list[Value], line: int) -> Va def int_op(self, type: RType, lhs: Value, rhs: Value, op: int, line: int) -> Value: return self.builder.int_op(type, lhs, rhs, op, line) - def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: - return self.builder.compare_tagged(lhs, rhs, op, line) - def compare_tuples(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: return self.builder.compare_tuples(lhs, rhs, op, line) diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index 021b7a1dbe90..ba62d71d0ad3 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -814,12 +814,6 @@ def translate_is_none(builder: IRBuilder, expr: Expression, negated: bool) -> Va def transform_basic_comparison( builder: IRBuilder, op: str, left: Value, right: Value, line: int ) -> Value: - if ( - is_int_rprimitive(left.type) - and is_int_rprimitive(right.type) - and op in int_comparison_op_mapping - ): - return builder.compare_tagged(left, right, op, line) if is_fixed_width_rtype(left.type) and op in int_comparison_op_mapping: if right.type == left.type: if left.type.is_signed: diff --git a/mypyc/irbuild/function.py b/mypyc/irbuild/function.py index b1785f40550e..c985e88b0e0c 100644 --- a/mypyc/irbuild/function.py +++ b/mypyc/irbuild/function.py @@ -889,9 +889,8 @@ def gen_native_func_call_and_return(fdef: FuncDef) -> None: call_impl, next_impl = BasicBlock(), BasicBlock() current_id = builder.load_int(i) - builder.builder.compare_tagged_condition( - passed_id, current_id, "==", call_impl, next_impl, line - ) + cond = builder.binary_op(passed_id, current_id, "==", line) + builder.add_bool_branch(cond, call_impl, next_impl) # Call the registered implementation builder.activate_block(call_impl) diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index f9bacb43bc3e..548b391030fe 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -1315,13 +1315,6 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value: return self.compare_strings(lreg, rreg, op, line) if is_bytes_rprimitive(ltype) and is_bytes_rprimitive(rtype) and op in ("==", "!="): return self.compare_bytes(lreg, rreg, op, line) - if ( - is_tagged(ltype) - and is_tagged(rtype) - and op in int_comparison_op_mapping - and op not in ("==", "!=") - ): - return self.compare_tagged(lreg, rreg, op, line) if is_bool_rprimitive(ltype) and is_bool_rprimitive(rtype) and op in BOOL_BINARY_OPS: if op in ComparisonOp.signed_ops: return self.bool_comparison_op(lreg, rreg, op, line) @@ -1384,16 +1377,6 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value: if is_fixed_width_rtype(lreg.type): return self.comparison_op(lreg, rreg, op_id, line) - # Mixed int comparisons - if op in ("==", "!="): - pass # TODO: Do we need anything here? - elif op in op in int_comparison_op_mapping: - if is_tagged(ltype) and is_subtype(rtype, ltype): - rreg = self.coerce(rreg, short_int_rprimitive, line) - return self.compare_tagged(lreg, rreg, op, line) - if is_tagged(rtype) and is_subtype(ltype, rtype): - lreg = self.coerce(lreg, short_int_rprimitive, line) - return self.compare_tagged(lreg, rreg, op, line) if is_float_rprimitive(ltype) or is_float_rprimitive(rtype): if isinstance(lreg, Integer): lreg = Float(float(lreg.numeric_value())) @@ -1445,18 +1428,16 @@ def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op] result = Register(bool_rprimitive) short_int_block, int_block, out = BasicBlock(), BasicBlock(), BasicBlock() - check_lhs = self.check_tagged_short_int(lhs, line) + check_lhs = self.check_tagged_short_int(lhs, line, negated=True) if op in ("==", "!="): - check = check_lhs + self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL)) else: # for non-equality logical ops (less/greater than, etc.), need to check both sides - check_rhs = self.check_tagged_short_int(rhs, line) - check = self.int_op(bit_rprimitive, check_lhs, check_rhs, IntOp.AND, line) - self.add(Branch(check, short_int_block, int_block, Branch.BOOL)) - self.activate_block(short_int_block) - eq = self.comparison_op(lhs, rhs, op_type, line) - self.add(Assign(result, eq, line)) - self.goto(out) + short_lhs = BasicBlock() + self.add(Branch(check_lhs, int_block, short_lhs, Branch.BOOL)) + self.activate_block(short_lhs) + check_rhs = self.check_tagged_short_int(rhs, line, negated=True) + self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL)) self.activate_block(int_block) if swap_op: args = [rhs, lhs] @@ -1469,62 +1450,12 @@ def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: else: call_result = call self.add(Assign(result, call_result, line)) - self.goto_and_activate(out) - return result - - def compare_tagged_condition( - self, lhs: Value, rhs: Value, op: str, true: BasicBlock, false: BasicBlock, line: int - ) -> None: - """Compare two tagged integers using given operator (conditional context). - - Assume lhs and rhs are tagged integers. - - Args: - lhs: Left operand - rhs: Right operand - op: Operation, one of '==', '!=', '<', '<=', '>', '<=' - true: Branch target if comparison is true - false: Branch target if comparison is false - """ - is_eq = op in ("==", "!=") - if (is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type)) or ( - is_eq and (is_short_int_rprimitive(lhs.type) or is_short_int_rprimitive(rhs.type)) - ): - # We can skip the tag check - check = self.comparison_op(lhs, rhs, int_comparison_op_mapping[op][0], line) - self.flush_keep_alives() - self.add(Branch(check, true, false, Branch.BOOL)) - return - op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op] - int_block, short_int_block = BasicBlock(), BasicBlock() - check_lhs = self.check_tagged_short_int(lhs, line, negated=True) - if is_eq or is_short_int_rprimitive(rhs.type): - self.flush_keep_alives() - self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL)) - else: - # For non-equality logical ops (less/greater than, etc.), need to check both sides - rhs_block = BasicBlock() - self.add(Branch(check_lhs, int_block, rhs_block, Branch.BOOL)) - self.activate_block(rhs_block) - check_rhs = self.check_tagged_short_int(rhs, line, negated=True) - self.flush_keep_alives() - self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL)) - # Arbitrary integers (slow path) - self.activate_block(int_block) - if swap_op: - args = [rhs, lhs] - else: - args = [lhs, rhs] - call = self.call_c(c_func_desc, args, line) - if negate_result: - self.add(Branch(call, false, true, Branch.BOOL)) - else: - self.flush_keep_alives() - self.add(Branch(call, true, false, Branch.BOOL)) - # Short integers (fast path) + self.goto(out) self.activate_block(short_int_block) eq = self.comparison_op(lhs, rhs, op_type, line) - self.add(Branch(eq, true, false, Branch.BOOL)) + self.add(Assign(result, eq, line)) + self.goto_and_activate(out) + return result def compare_strings(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: """Compare two strings""" @@ -2309,7 +2240,8 @@ def builtin_len(self, val: Value, line: int, use_pyssize_t: bool = False) -> Val length = self.gen_method_call(val, "__len__", [], int_rprimitive, line) length = self.coerce(length, int_rprimitive, line) ok, fail = BasicBlock(), BasicBlock() - self.compare_tagged_condition(length, Integer(0), ">=", ok, fail, line) + cond = self.binary_op(length, Integer(0), ">=", line) + self.add_bool_branch(cond, ok, fail) self.activate_block(fail) self.add( RaiseStandardError( diff --git a/mypyc/lower/int_ops.py b/mypyc/lower/int_ops.py index 40fba7af4f4d..5255a64b647d 100644 --- a/mypyc/lower/int_ops.py +++ b/mypyc/lower/int_ops.py @@ -13,3 +13,23 @@ def lower_int_eq(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Va @lower_binary_op("int_ne") def lower_int_ne(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return builder.compare_tagged(args[0], args[1], "!=", line) + + +@lower_binary_op("int_lt") +def lower_int_lt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], "<", line) + + +@lower_binary_op("int_le") +def lower_int_le(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], "<=", line) + + +@lower_binary_op("int_gt") +def lower_int_gt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], ">", line) + + +@lower_binary_op("int_ge") +def lower_int_ge(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], ">=", line) diff --git a/mypyc/primitives/int_ops.py b/mypyc/primitives/int_ops.py index 4103fe349a74..029d71606886 100644 --- a/mypyc/primitives/int_ops.py +++ b/mypyc/primitives/int_ops.py @@ -122,6 +122,10 @@ def int_binary_primitive( int_eq = int_binary_primitive(op="==", primitive_name="int_eq", return_type=bit_rprimitive) int_ne = int_binary_primitive(op="!=", primitive_name="int_ne", return_type=bit_rprimitive) +int_lt = int_binary_primitive(op="<", primitive_name="int_lt", return_type=bit_rprimitive) +int_le = int_binary_primitive(op="<=", primitive_name="int_le", return_type=bit_rprimitive) +int_gt = int_binary_primitive(op=">", primitive_name="int_gt", return_type=bit_rprimitive) +int_ge = int_binary_primitive(op=">=", primitive_name="int_ge", return_type=bit_rprimitive) def int_binary_op( diff --git a/mypyc/test-data/analysis.test b/mypyc/test-data/analysis.test index 8e067aed4d79..35677b8ea56d 100644 --- a/mypyc/test-data/analysis.test +++ b/mypyc/test-data/analysis.test @@ -148,40 +148,27 @@ def f(n: int) -> None: [out] def f(n): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4, m :: int + r0 :: bit + r1, m :: int L0: L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L3 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L5 :: bool -L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L5 :: bool -L4: - r4 = CPyTagged_Add(n, 2) - n = r4 + r1 = CPyTagged_Add(n, 2) + n = r1 m = n goto L1 -L5: +L3: return 1 (0, 0) {n} {n} (1, 0) {n} {n} (1, 1) {n} {n} -(1, 2) {n} {n} (2, 0) {n} {n} (2, 1) {n} {n} +(2, 2) {n} {m, n} +(2, 3) {m, n} {m, n} (3, 0) {n} {n} -(3, 1) {n} {n} -(4, 0) {n} {n} -(4, 1) {n} {n} -(4, 2) {n} {m, n} -(4, 3) {m, n} {m, n} -(5, 0) {n} {n} [case testMultiPass_Liveness] def f(n: int) -> None: @@ -195,67 +182,40 @@ def f(n: int) -> None: [out] def f(n): n, x, y :: int - r0 :: native_int - r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1 :: bit L0: x = 2 y = 2 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 2 + if r0 goto L2 else goto L6 :: bool L2: - r2 = CPyTagged_IsLt_(n, 2) - if r2 goto L4 else goto L10 :: bool + n = y L3: - r3 = n < 2 :: signed - if r3 goto L4 else goto L10 :: bool + r1 = int_lt n, 4 + if r1 goto L4 else goto L5 :: bool L4: - n = y -L5: - r4 = n & 1 - r5 = r4 != 0 - if r5 goto L6 else goto L7 :: bool -L6: - r6 = CPyTagged_IsLt_(n, 4) - if r6 goto L8 else goto L9 :: bool -L7: - r7 = n < 4 :: signed - if r7 goto L8 else goto L9 :: bool -L8: n = 2 n = x - goto L5 -L9: + goto L3 +L5: goto L1 -L10: +L6: return 1 (0, 0) {n} {n, x} (0, 1) {n, x} {n, x, y} (0, 2) {n, x, y} {n, x, y} -(1, 0) {n, x, y} {n, r0, x, y} -(1, 1) {n, r0, x, y} {n, r1, x, y} -(1, 2) {n, r1, x, y} {n, x, y} -(2, 0) {n, x, y} {r2, x, y} -(2, 1) {r2, x, y} {x, y} -(3, 0) {n, x, y} {r3, x, y} -(3, 1) {r3, x, y} {x, y} -(4, 0) {x, y} {n, x, y} -(4, 1) {n, x, y} {n, x, y} -(5, 0) {n, x, y} {n, r4, x, y} -(5, 1) {n, r4, x, y} {n, r5, x, y} -(5, 2) {n, r5, x, y} {n, x, y} -(6, 0) {n, x, y} {n, r6, x, y} -(6, 1) {n, r6, x, y} {n, x, y} -(7, 0) {n, x, y} {n, r7, x, y} -(7, 1) {n, r7, x, y} {n, x, y} -(8, 0) {x, y} {x, y} -(8, 1) {x, y} {n, x, y} -(8, 2) {n, x, y} {n, x, y} -(9, 0) {n, x, y} {n, x, y} -(10, 0) {} {} +(1, 0) {n, x, y} {r0, x, y} +(1, 1) {r0, x, y} {x, y} +(2, 0) {x, y} {n, x, y} +(2, 1) {n, x, y} {n, x, y} +(3, 0) {n, x, y} {n, r1, x, y} +(3, 1) {n, r1, x, y} {n, x, y} +(4, 0) {x, y} {x, y} +(4, 1) {x, y} {n, x, y} +(4, 2) {n, x, y} {n, x, y} +(5, 0) {n, x, y} {n, x, y} +(6, 0) {} {} [case testCall_Liveness] def f(x: int) -> int: @@ -296,80 +256,35 @@ def f(a: int) -> None: [out] def f(a): a :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit y, x :: int L0: L1: - r0 = a & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_lt a, a + if r0 goto L2 else goto L6 :: bool L2: - r2 = a & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool L3: - r4 = CPyTagged_IsLt_(a, a) - if r4 goto L5 else goto L12 :: bool + r1 = int_lt a, a + if r1 goto L4 else goto L5 :: bool L4: - r5 = a < a :: signed - if r5 goto L5 else goto L12 :: bool -L5: -L6: - r6 = a & 1 - r7 = r6 != 0 - if r7 goto L8 else goto L7 :: bool -L7: - r8 = a & 1 - r9 = r8 != 0 - if r9 goto L8 else goto L9 :: bool -L8: - r10 = CPyTagged_IsLt_(a, a) - if r10 goto L10 else goto L11 :: bool -L9: - r11 = a < a :: signed - if r11 goto L10 else goto L11 :: bool -L10: y = a - goto L6 -L11: + goto L3 +L5: x = a goto L1 -L12: +L6: return 1 (0, 0) {a} {a} (1, 0) {a, x, y} {a, x, y} (1, 1) {a, x, y} {a, x, y} -(1, 2) {a, x, y} {a, x, y} (2, 0) {a, x, y} {a, x, y} -(2, 1) {a, x, y} {a, x, y} -(2, 2) {a, x, y} {a, x, y} (3, 0) {a, x, y} {a, x, y} (3, 1) {a, x, y} {a, x, y} (4, 0) {a, x, y} {a, x, y} (4, 1) {a, x, y} {a, x, y} (5, 0) {a, x, y} {a, x, y} +(5, 1) {a, x, y} {a, x, y} (6, 0) {a, x, y} {a, x, y} -(6, 1) {a, x, y} {a, x, y} -(6, 2) {a, x, y} {a, x, y} -(7, 0) {a, x, y} {a, x, y} -(7, 1) {a, x, y} {a, x, y} -(7, 2) {a, x, y} {a, x, y} -(8, 0) {a, x, y} {a, x, y} -(8, 1) {a, x, y} {a, x, y} -(9, 0) {a, x, y} {a, x, y} -(9, 1) {a, x, y} {a, x, y} -(10, 0) {a, x, y} {a, x, y} -(10, 1) {a, x, y} {a, x, y} -(11, 0) {a, x, y} {a, x, y} -(11, 1) {a, x, y} {a, x, y} -(12, 0) {a, x, y} {a, x, y} [case testTrivial_BorrowedArgument] def f(a: int, b: int) -> int: @@ -441,55 +356,33 @@ def f(a: int) -> int: [out] def f(a): a, sum, i :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6, r7 :: int + r0 :: bit + r1, r2 :: int L0: sum = 0 i = 0 L1: - r0 = i & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_le i, a + if r0 goto L2 else goto L3 :: bool L2: - r2 = a & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(a, i) - if r4 goto L6 else goto L5 :: bool -L4: - r5 = i <= a :: signed - if r5 goto L5 else goto L6 :: bool -L5: - r6 = CPyTagged_Add(sum, i) - sum = r6 - r7 = CPyTagged_Add(i, 2) - i = r7 + r1 = CPyTagged_Add(sum, i) + sum = r1 + r2 = CPyTagged_Add(i, 2) + i = r2 goto L1 -L6: +L3: return sum (0, 0) {a} {a} (0, 1) {a} {a} (0, 2) {a} {a} (1, 0) {a} {a} (1, 1) {a} {a} -(1, 2) {a} {a} (2, 0) {a} {a} (2, 1) {a} {a} (2, 2) {a} {a} +(2, 3) {a} {a} +(2, 4) {a} {a} (3, 0) {a} {a} -(3, 1) {a} {a} -(4, 0) {a} {a} -(4, 1) {a} {a} -(5, 0) {a} {a} -(5, 1) {a} {a} -(5, 2) {a} {a} -(5, 3) {a} {a} -(5, 4) {a} {a} -(6, 0) {a} {a} [case testError] def f(x: List[int]) -> None: pass # E: Name "List" is not defined \ diff --git a/mypyc/test-data/exceptions.test b/mypyc/test-data/exceptions.test index ed43b86ebdb4..1ec03dd9a671 100644 --- a/mypyc/test-data/exceptions.test +++ b/mypyc/test-data/exceptions.test @@ -111,56 +111,42 @@ def sum(a: List[int], l: int) -> int: def sum(a, l): a :: list l, sum, i :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: object - r7, r8, r9, r10 :: int + r0 :: bit + r1 :: object + r2, r3, r4, r5 :: int L0: sum = 0 i = 0 L1: - r0 = i & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_lt i, l + if r0 goto L2 else goto L7 :: bool L2: - r2 = l & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool + r1 = CPyList_GetItemBorrow(a, i) + if is_error(r1) goto L8 (error at sum:6) else goto L3 L3: - r4 = CPyTagged_IsLt_(i, l) - if r4 goto L5 else goto L10 :: bool + r2 = unbox(int, r1) + if is_error(r2) goto L8 (error at sum:6) else goto L4 L4: - r5 = i < l :: signed - if r5 goto L5 else goto L10 :: bool -L5: - r6 = CPyList_GetItemBorrow(a, i) - if is_error(r6) goto L11 (error at sum:6) else goto L6 -L6: - r7 = unbox(int, r6) - if is_error(r7) goto L11 (error at sum:6) else goto L7 -L7: - r8 = CPyTagged_Add(sum, r7) + r3 = CPyTagged_Add(sum, r2) dec_ref sum :: int - dec_ref r7 :: int - sum = r8 - r9 = CPyTagged_Add(i, 2) + dec_ref r2 :: int + sum = r3 + r4 = CPyTagged_Add(i, 2) dec_ref i :: int - i = r9 + i = r4 goto L1 -L8: +L5: return sum -L9: - r10 = :: int - return r10 -L10: +L6: + r5 = :: int + return r5 +L7: dec_ref i :: int - goto L8 -L11: + goto L5 +L8: dec_ref sum :: int dec_ref i :: int - goto L9 + goto L6 [case testTryExcept] def g() -> None: diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 981460dae371..164fc213a8a2 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -76,27 +76,13 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L5 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L5 :: bool -L4: x = 2 -L5: +L2: return x [case testIfElse] @@ -109,30 +95,16 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L5 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L5 :: bool -L4: x = 2 - goto L6 -L5: + goto L3 +L2: x = 4 -L6: +L3: return x [case testAnd1] @@ -145,48 +117,19 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L3 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool + r1 = int_gt x, y + if r1 goto L2 else goto L3 :: bool L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L9 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L9 :: bool -L4: - r6 = x & 1 - r7 = r6 != 0 - if r7 goto L6 else goto L5 :: bool -L5: - r8 = y & 1 - r9 = r8 != 0 - if r9 goto L6 else goto L7 :: bool -L6: - r10 = CPyTagged_IsLt_(y, x) - if r10 goto L8 else goto L9 :: bool -L7: - r11 = x > y :: signed - if r11 goto L8 else goto L9 :: bool -L8: x = 2 - goto L10 -L9: + goto L4 +L3: x = 4 -L10: +L4: return x [case testAnd2] @@ -221,48 +164,19 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L2 else goto L1 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool + r1 = int_gt x, y + if r1 goto L2 else goto L3 :: bool L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L8 else goto L4 :: bool -L3: - r5 = x < y :: signed - if r5 goto L8 else goto L4 :: bool -L4: - r6 = x & 1 - r7 = r6 != 0 - if r7 goto L6 else goto L5 :: bool -L5: - r8 = y & 1 - r9 = r8 != 0 - if r9 goto L6 else goto L7 :: bool -L6: - r10 = CPyTagged_IsLt_(y, x) - if r10 goto L8 else goto L9 :: bool -L7: - r11 = x > y :: signed - if r11 goto L8 else goto L9 :: bool -L8: x = 2 - goto L10 -L9: + goto L4 +L3: x = 4 -L10: +L4: return x [case testOr2] @@ -295,27 +209,13 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L2 else goto L1 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L5 else goto L4 :: bool -L3: - r5 = x < y :: signed - if r5 goto L5 else goto L4 :: bool -L4: x = 2 -L5: +L2: return x [case testNotAnd] @@ -326,45 +226,16 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool + r1 = int_gt x, y + if r1 goto L3 else goto L2 :: bool L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L8 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L8 :: bool -L4: - r6 = x & 1 - r7 = r6 != 0 - if r7 goto L6 else goto L5 :: bool -L5: - r8 = y & 1 - r9 = r8 != 0 - if r9 goto L6 else goto L7 :: bool -L6: - r10 = CPyTagged_IsLt_(y, x) - if r10 goto L9 else goto L8 :: bool -L7: - r11 = x > y :: signed - if r11 goto L9 else goto L8 :: bool -L8: x = 2 -L9: +L3: return x [case testWhile] @@ -375,31 +246,17 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: int + r0 :: bit + r1 :: int L0: L1: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_gt x, y + if r0 goto L2 else goto L3 :: bool L2: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(y, x) - if r4 goto L5 else goto L6 :: bool -L4: - r5 = x > y :: signed - if r5 goto L5 else goto L6 :: bool -L5: - r6 = CPyTagged_Subtract(x, y) - x = r6 + r1 = CPyTagged_Subtract(x, y) + x = r1 goto L1 -L6: +L3: return x [case testWhile2] @@ -411,32 +268,18 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: int + r0 :: bit + r1 :: int L0: x = 2 L1: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_gt x, y + if r0 goto L2 else goto L3 :: bool L2: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(y, x) - if r4 goto L5 else goto L6 :: bool -L4: - r5 = x > y :: signed - if r5 goto L5 else goto L6 :: bool -L5: - r6 = CPyTagged_Subtract(x, y) - x = r6 + r1 = CPyTagged_Subtract(x, y) + x = r1 goto L1 -L6: +L3: return x [case testImplicitNoneReturn] @@ -466,30 +309,16 @@ def f(x: int, y: int) -> None: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L5 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L5 :: bool -L4: x = 2 - goto L6 -L5: + goto L3 +L2: y = 4 -L6: +L3: return 1 [case testRecursion] @@ -501,29 +330,21 @@ def f(n: int) -> int: [out] def f(n): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4, r5, r6, r7, r8 :: int + r0 :: bit + r1, r2, r3, r4, r5 :: int L0: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_le n, 2 + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsLt_(2, n) - if r2 goto L4 else goto L3 :: bool + return 2 L2: - r3 = n <= 2 :: signed - if r3 goto L3 else goto L4 :: bool + r1 = CPyTagged_Subtract(n, 2) + r2 = f(r1) + r3 = CPyTagged_Subtract(n, 4) + r4 = f(r3) + r5 = CPyTagged_Add(r2, r4) + return r5 L3: - return 2 -L4: - r4 = CPyTagged_Subtract(n, 2) - r5 = f(r4) - r6 = CPyTagged_Subtract(n, 4) - r7 = f(r6) - r8 = CPyTagged_Add(r5, r7) - return r8 -L5: unreachable [case testReportTypeCheckError] @@ -550,33 +371,25 @@ def f(n: int) -> int: [out] def f(n): n :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit x :: int - r4 :: bit + r1 :: bit L0: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_lt n, 0 + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsLt_(n, 0) - if r2 goto L3 else goto L4 :: bool + x = 2 + goto L6 L2: - r3 = n < 0 :: signed - if r3 goto L3 else goto L4 :: bool + r1 = int_eq n, 0 + if r1 goto L3 else goto L4 :: bool L3: x = 2 - goto L8 + goto L5 L4: - r4 = int_eq n, 0 - if r4 goto L5 else goto L6 :: bool + x = 4 L5: - x = 2 - goto L7 L6: - x = 4 -L7: -L8: return x [case testUnaryMinus] @@ -1272,27 +1085,19 @@ def f(x: int) -> int: [out] def absolute_value(x): x :: int - r0 :: native_int - r1, r2, r3 :: bit - r4, r5 :: int + r0 :: bit + r1, r2 :: int L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_gt x, 0 + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsLt_(0, x) - if r2 goto L3 else goto L4 :: bool + r1 = x + goto L3 L2: - r3 = x > 0 :: signed - if r3 goto L3 else goto L4 :: bool + r2 = CPyTagged_Negate(x) + r1 = r2 L3: - r4 = x - goto L5 -L4: - r5 = CPyTagged_Negate(x) - r4 = r5 -L5: - return r4 + return r1 def call_native_function(x): x, r0 :: int L0: @@ -2078,7 +1883,7 @@ L1: r11 = load_mem r10 :: native_int* keep_alive r1 r12 = r11 << 1 - r13 = r9 < r12 :: signed + r13 = int_lt r9, r12 if r13 goto L2 else goto L8 :: bool L2: r14 = CPyList_GetItemUnsafe(r1, r9) @@ -2148,7 +1953,7 @@ L1: r11 = load_mem r10 :: native_int* keep_alive r1 r12 = r11 << 1 - r13 = r9 < r12 :: signed + r13 = int_lt r9, r12 if r13 goto L2 else goto L8 :: bool L2: r14 = CPyList_GetItemUnsafe(r1, r9) @@ -2215,7 +2020,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive l r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(l, r0) @@ -2241,7 +2046,7 @@ L5: r16 = load_mem r15 :: native_int* keep_alive l r17 = r16 << 1 - r18 = r14 < r17 :: signed + r18 = int_lt r14, r17 if r18 goto L6 else goto L8 :: bool L6: r19 = CPyList_GetItemUnsafe(l, r14) @@ -2504,60 +2309,24 @@ L0: return x def f(x, y, z): x, y, z, r0, r1 :: int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit - r10 :: bool - r11 :: int - r12 :: native_int - r13 :: bit - r14 :: native_int - r15, r16, r17 :: bit - r18 :: bool - r19 :: bit + r2 :: bit + r3 :: bool + r4 :: int + r5 :: bit L0: r0 = g(x) r1 = g(y) - r2 = r0 & 1 - r3 = r2 == 0 - r4 = r1 & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool + r2 = int_lt r0, r1 + if r2 goto L2 else goto L1 :: bool L1: - r7 = r0 < r1 :: signed - r8 = r7 + r3 = r2 goto L3 L2: - r9 = CPyTagged_IsLt_(r0, r1) - r8 = r9 + r4 = g(z) + r5 = int_gt r1, r4 + r3 = r5 L3: - if r8 goto L5 else goto L4 :: bool -L4: - r10 = r8 - goto L9 -L5: - r11 = g(z) - r12 = r1 & 1 - r13 = r12 == 0 - r14 = r11 & 1 - r15 = r14 == 0 - r16 = r13 & r15 - if r16 goto L6 else goto L7 :: bool -L6: - r17 = r1 > r11 :: signed - r18 = r17 - goto L8 -L7: - r19 = CPyTagged_IsLt_(r11, r1) - r18 = r19 -L8: - r10 = r18 -L9: - return r10 + return r3 [case testEq] class A: @@ -3577,7 +3346,7 @@ L0: r0 = 8 i = r0 L1: - r1 = r0 < 24 :: signed + r1 = int_lt r0, 24 if r1 goto L2 else goto L4 :: bool L2: r2 = CPyTagged_Add(sum, i) diff --git a/mypyc/test-data/irbuild-bool.test b/mypyc/test-data/irbuild-bool.test index f0b0b480bc0d..795a3360fcd2 100644 --- a/mypyc/test-data/irbuild-bool.test +++ b/mypyc/test-data/irbuild-bool.test @@ -272,59 +272,23 @@ def lt1(x, y): x :: bool y :: int r0 :: bool - r1 :: short_int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit + r1 :: int + r2 :: bit L0: r0 = x << 1 - r1 = extend r0: builtins.bool to short_int - r2 = r1 & 1 - r3 = r2 == 0 - r4 = y & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool -L1: - r7 = r1 < y :: signed - r8 = r7 - goto L3 -L2: - r9 = CPyTagged_IsLt_(r1, y) - r8 = r9 -L3: - return r8 + r1 = extend r0: builtins.bool to builtins.int + r2 = int_lt r1, y + return r2 def lt2(x, y): x :: int y, r0 :: bool - r1 :: short_int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit + r1 :: int + r2 :: bit L0: r0 = y << 1 - r1 = extend r0: builtins.bool to short_int - r2 = x & 1 - r3 = r2 == 0 - r4 = r1 & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool -L1: - r7 = x < r1 :: signed - r8 = r7 - goto L3 -L2: - r9 = CPyTagged_IsLt_(x, r1) - r8 = r9 -L3: - return r8 + r1 = extend r0: builtins.bool to builtins.int + r2 = int_lt x, r1 + return r2 def gt1(x, y): x :: bool y, r0 :: i64 diff --git a/mypyc/test-data/irbuild-dunders.test b/mypyc/test-data/irbuild-dunders.test index b50b6eeae162..1796a7e2160e 100644 --- a/mypyc/test-data/irbuild-dunders.test +++ b/mypyc/test-data/irbuild-dunders.test @@ -15,24 +15,16 @@ L0: def f(c): c :: __main__.C r0 :: int - r1 :: native_int - r2, r3, r4 :: bit - r5 :: bool + r1 :: bit + r2 :: bool L0: r0 = c.__len__() - r1 = r0 & 1 - r2 = r1 != 0 - if r2 goto L1 else goto L2 :: bool + r1 = int_ge r0, 0 + if r1 goto L2 else goto L1 :: bool L1: - r3 = CPyTagged_IsLt_(r0, 0) - if r3 goto L3 else goto L4 :: bool -L2: - r4 = r0 >= 0 :: signed - if r4 goto L4 else goto L3 :: bool -L3: - r5 = raise ValueError('__len__() should return >= 0') + r2 = raise ValueError('__len__() should return >= 0') unreachable -L4: +L2: return r0 [case testDundersSetItem] diff --git a/mypyc/test-data/irbuild-int.test b/mypyc/test-data/irbuild-int.test index 1489f2f470dd..b1a712103e70 100644 --- a/mypyc/test-data/irbuild-int.test +++ b/mypyc/test-data/irbuild-int.test @@ -25,9 +25,7 @@ def f(x: int) -> int: [out] def f(x): x :: int - r0, r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1, r2, r3, r4 :: bit L0: r0 = int_eq x, 6 if r0 goto L1 else goto L2 :: bool @@ -49,22 +47,15 @@ L6: L7: return 8 L8: - r4 = x & 1 - r5 = r4 != 0 - if r5 goto L9 else goto L10 :: bool + r4 = int_lt x, 8 + if r4 goto L9 else goto L10 :: bool L9: - r6 = CPyTagged_IsLt_(x, 8) - if r6 goto L11 else goto L12 :: bool + return 10 L10: - r7 = x < 8 :: signed - if r7 goto L11 else goto L12 :: bool L11: - return 10 L12: L13: L14: -L15: -L16: return 12 [case testIntMin] @@ -73,36 +64,18 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: bool - r7 :: bit - r8 :: int -L0: - r0 = y & 1 - r1 = r0 == 0 - r2 = x & 1 - r3 = r2 == 0 - r4 = r1 & r3 - if r4 goto L1 else goto L2 :: bool + r0 :: bit + r1 :: int +L0: + r0 = int_lt y, x + if r0 goto L1 else goto L2 :: bool L1: - r5 = y < x :: signed - r6 = r5 + r1 = y goto L3 L2: - r7 = CPyTagged_IsLt_(y, x) - r6 = r7 + r1 = x L3: - if r6 goto L4 else goto L5 :: bool -L4: - r8 = y - goto L6 -L5: - r8 = x -L6: - return r8 + return r1 [case testIntFloorDivideByPowerOfTwo] def divby1(x: int) -> int: diff --git a/mypyc/test-data/irbuild-lists.test b/mypyc/test-data/irbuild-lists.test index 80c4fe5fcd5e..ced4646922a3 100644 --- a/mypyc/test-data/irbuild-lists.test +++ b/mypyc/test-data/irbuild-lists.test @@ -230,7 +230,7 @@ L0: r3 = 0 i = r3 L1: - r4 = r3 < r2 :: signed + r4 = int_lt r3, r2 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItem(l, i) @@ -357,7 +357,7 @@ L1: r5 = load_mem r4 :: native_int* keep_alive source r6 = r5 << 1 - r7 = r3 < r6 :: signed + r7 = int_lt r3, r6 if r7 goto L2 else goto L4 :: bool L2: r8 = CPyList_GetItemUnsafe(source, r3) @@ -382,7 +382,7 @@ L5: r19 = load_mem r18 :: native_int* keep_alive source r20 = r19 << 1 - r21 = r17 < r20 :: signed + r21 = int_lt r17, r20 if r21 goto L6 else goto L8 :: bool L6: r22 = CPyList_GetItemUnsafe(source, r17) @@ -398,6 +398,7 @@ L7: L8: b = r16 return 1 + [case testGeneratorNext] from typing import List, Optional @@ -425,7 +426,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive x r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(x, r0) @@ -504,7 +505,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive a r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(a, r0) @@ -533,7 +534,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive a r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(a, r0) diff --git a/mypyc/test-data/irbuild-set.test b/mypyc/test-data/irbuild-set.test index a56ebe3438fa..51feab332593 100644 --- a/mypyc/test-data/irbuild-set.test +++ b/mypyc/test-data/irbuild-set.test @@ -115,7 +115,7 @@ L1: r11 = load_mem r10 :: native_int* keep_alive tmp_list r12 = r11 << 1 - r13 = r9 < r12 :: signed + r13 = int_lt r9, r12 if r13 goto L2 else goto L4 :: bool L2: r14 = CPyList_GetItemUnsafe(tmp_list, r9) @@ -234,7 +234,7 @@ L0: r1 = 2 x = r1 L1: - r2 = r1 < 12 :: signed + r2 = int_lt r1, 12 if r2 goto L2 else goto L4 :: bool L2: r3 = f(x) @@ -265,7 +265,7 @@ L0: r1 = 2 x = r1 L1: - r2 = r1 < 12 :: signed + r2 = int_lt r1, 12 if r2 goto L2 else goto L4 :: bool L2: r3 = f(x) @@ -323,27 +323,22 @@ def test(): r19 :: bit r20 :: object r21, z :: int - r22 :: native_int - r23 :: bit - r24 :: native_int - r25, r26, r27 :: bit - r28 :: bool - r29 :: bit - r30 :: int - r31 :: object - r32 :: i32 - r33 :: bit - r34 :: short_int - r35, r36, r37 :: object - r38, y, r39 :: int - r40 :: object - r41 :: i32 - r42, r43 :: bit - r44, r45, r46 :: object - r47, x, r48 :: int - r49 :: object - r50 :: i32 - r51, r52 :: bit + r22 :: bit + r23 :: int + r24 :: object + r25 :: i32 + r26 :: bit + r27 :: short_int + r28, r29, r30 :: object + r31, y, r32 :: int + r33 :: object + r34 :: i32 + r35, r36 :: bit + r37, r38, r39 :: object + r40, x, r41 :: int + r42 :: object + r43 :: i32 + r44, r45 :: bit a :: set L0: r0 = PyList_New(5) @@ -374,73 +369,60 @@ L1: r17 = load_mem r16 :: native_int* keep_alive tmp_list r18 = r17 << 1 - r19 = r15 < r18 :: signed - if r19 goto L2 else goto L9 :: bool + r19 = int_lt r15, r18 + if r19 goto L2 else goto L6 :: bool L2: r20 = CPyList_GetItemUnsafe(tmp_list, r15) r21 = unbox(int, r20) z = r21 - r22 = z & 1 - r23 = r22 == 0 - r24 = 8 & 1 - r25 = r24 == 0 - r26 = r23 & r25 - if r26 goto L3 else goto L4 :: bool + r22 = int_lt z, 8 + if r22 goto L4 else goto L3 :: bool L3: - r27 = z < 8 :: signed - r28 = r27 goto L5 L4: - r29 = CPyTagged_IsLt_(z, 8) - r28 = r29 + r23 = f1(z) + r24 = box(int, r23) + r25 = PyList_Append(r14, r24) + r26 = r25 >= 0 :: signed L5: - if r28 goto L7 else goto L6 :: bool + r27 = r15 + 2 + r15 = r27 + goto L1 L6: - goto L8 + r28 = PyObject_GetIter(r14) + r29 = PyObject_GetIter(r28) L7: - r30 = f1(z) - r31 = box(int, r30) - r32 = PyList_Append(r14, r31) - r33 = r32 >= 0 :: signed + r30 = PyIter_Next(r29) + if is_error(r30) goto L10 else goto L8 L8: - r34 = r15 + 2 - r15 = r34 - goto L1 + r31 = unbox(int, r30) + y = r31 + r32 = f2(y) + r33 = box(int, r32) + r34 = PyList_Append(r13, r33) + r35 = r34 >= 0 :: signed L9: - r35 = PyObject_GetIter(r14) - r36 = PyObject_GetIter(r35) + goto L7 L10: - r37 = PyIter_Next(r36) - if is_error(r37) goto L13 else goto L11 + r36 = CPy_NoErrOccured() L11: - r38 = unbox(int, r37) - y = r38 - r39 = f2(y) - r40 = box(int, r39) - r41 = PyList_Append(r13, r40) - r42 = r41 >= 0 :: signed + r37 = PyObject_GetIter(r13) + r38 = PyObject_GetIter(r37) L12: - goto L10 + r39 = PyIter_Next(r38) + if is_error(r39) goto L15 else goto L13 L13: - r43 = CPy_NoErrOccured() + r40 = unbox(int, r39) + x = r40 + r41 = f3(x) + r42 = box(int, r41) + r43 = PySet_Add(r12, r42) + r44 = r43 >= 0 :: signed L14: - r44 = PyObject_GetIter(r13) - r45 = PyObject_GetIter(r44) + goto L12 L15: - r46 = PyIter_Next(r45) - if is_error(r46) goto L18 else goto L16 + r45 = CPy_NoErrOccured() L16: - r47 = unbox(int, r46) - x = r47 - r48 = f3(x) - r49 = box(int, r48) - r50 = PySet_Add(r12, r49) - r51 = r50 >= 0 :: signed -L17: - goto L15 -L18: - r52 = CPy_NoErrOccured() -L19: a = r12 return 1 diff --git a/mypyc/test-data/irbuild-singledispatch.test b/mypyc/test-data/irbuild-singledispatch.test index 10970a385966..e1053397546f 100644 --- a/mypyc/test-data/irbuild-singledispatch.test +++ b/mypyc/test-data/irbuild-singledispatch.test @@ -81,7 +81,7 @@ L3: if r17 goto L4 else goto L7 :: bool L4: r18 = unbox(int, r6) - r19 = r18 == 0 + r19 = int_eq r18, 0 if r19 goto L5 else goto L6 :: bool L5: r20 = unbox(int, arg) diff --git a/mypyc/test-data/irbuild-statements.test b/mypyc/test-data/irbuild-statements.test index b7c67730a05f..ed97c4cd4138 100644 --- a/mypyc/test-data/irbuild-statements.test +++ b/mypyc/test-data/irbuild-statements.test @@ -16,7 +16,7 @@ L0: r0 = 0 i = r0 L1: - r1 = r0 < 10 :: signed + r1 = int_lt r0, 10 if r1 goto L2 else goto L4 :: bool L2: r2 = CPyTagged_Add(x, i) @@ -36,39 +36,21 @@ def f(a: int) -> None: [out] def f(a): a, r0, i :: int - r1 :: native_int - r2 :: bit - r3 :: native_int - r4, r5, r6 :: bit - r7 :: bool - r8 :: bit - r9 :: int + r1 :: bit + r2 :: int L0: r0 = 0 i = r0 L1: - r1 = r0 & 1 - r2 = r1 == 0 - r3 = a & 1 - r4 = r3 == 0 - r5 = r2 & r4 - if r5 goto L2 else goto L3 :: bool + r1 = int_lt r0, a + if r1 goto L2 else goto L4 :: bool L2: - r6 = r0 < a :: signed - r7 = r6 - goto L4 L3: - r8 = CPyTagged_IsLt_(r0, a) - r7 = r8 -L4: - if r7 goto L5 else goto L7 :: bool -L5: -L6: - r9 = CPyTagged_Add(r0, 2) - r0 = r9 - i = r9 + r2 = CPyTagged_Add(r0, 2) + r0 = r2 + i = r2 goto L1 -L7: +L4: return 1 [case testForInNegativeRange] @@ -85,7 +67,7 @@ L0: r0 = 20 i = r0 L1: - r1 = r0 > 0 :: signed + r1 = int_gt r0, 0 if r1 goto L2 else goto L4 :: bool L2: L3: @@ -104,22 +86,14 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L3 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L5 :: bool L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L5 :: bool -L4: -L5: return 1 [case testBreakFor] @@ -136,7 +110,7 @@ L0: r0 = 0 n = r0 L1: - r1 = r0 < 10 :: signed + r1 = int_lt r0, 10 if r1 goto L2 else goto L4 :: bool L2: goto L4 @@ -158,36 +132,19 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L6 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L10 :: bool L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L10 :: bool + r1 = int_lt n, 8 + if r1 goto L4 else goto L5 :: bool L4: L5: - r4 = n & 1 - r5 = r4 != 0 - if r5 goto L6 else goto L7 :: bool L6: - r6 = CPyTagged_IsLt_(n, 8) - if r6 goto L8 else goto L9 :: bool -L7: - r7 = n < 8 :: signed - if r7 goto L8 else goto L9 :: bool -L8: -L9: -L10: return 1 [case testContinue] @@ -198,23 +155,15 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L3 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L5 :: bool -L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L5 :: bool -L4: goto L1 -L5: +L3: return 1 [case testContinueFor] @@ -231,7 +180,7 @@ L0: r0 = 0 n = r0 L1: - r1 = r0 < 10 :: signed + r1 = int_lt r0, 10 if r1 goto L2 else goto L4 :: bool L2: L3: @@ -252,38 +201,21 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L6 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L10 :: bool L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L10 :: bool + r1 = int_lt n, 8 + if r1 goto L4 else goto L5 :: bool L4: + goto L3 L5: - r4 = n & 1 - r5 = r4 != 0 - if r5 goto L6 else goto L7 :: bool -L6: - r6 = CPyTagged_IsLt_(n, 8) - if r6 goto L8 else goto L9 :: bool -L7: - r7 = n < 8 :: signed - if r7 goto L8 else goto L9 :: bool -L8: - goto L5 -L9: goto L1 -L10: +L6: return 1 [case testForList] @@ -314,7 +246,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive ls r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(ls, r0) @@ -963,7 +895,7 @@ L1: r3 = load_mem r2 :: native_int* keep_alive a r4 = r3 << 1 - r5 = r1 < r4 :: signed + r5 = int_lt r1, r4 if r5 goto L2 else goto L4 :: bool L2: r6 = CPyList_GetItemUnsafe(a, r1) @@ -1045,7 +977,7 @@ L1: r3 = load_mem r2 :: native_int* keep_alive a r4 = r3 << 1 - r5 = r0 < r4 :: signed + r5 = int_lt r0, r4 if r5 goto L2 else goto L7 :: bool L2: r6 = PyIter_Next(r1) @@ -1100,10 +1032,10 @@ L2: r5 = load_mem r4 :: native_int* keep_alive b r6 = r5 << 1 - r7 = r1 < r6 :: signed + r7 = int_lt r1, r6 if r7 goto L3 else goto L6 :: bool L3: - r8 = r2 < 10 :: signed + r8 = int_lt r2, 10 if r8 goto L4 else goto L6 :: bool L4: r9 = unbox(bool, r3) diff --git a/mypyc/test-data/irbuild-tuple.test b/mypyc/test-data/irbuild-tuple.test index ab0e2fa09a9d..342bb19b5360 100644 --- a/mypyc/test-data/irbuild-tuple.test +++ b/mypyc/test-data/irbuild-tuple.test @@ -147,7 +147,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive xs r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPySequenceTuple_GetItem(xs, r0) @@ -279,7 +279,7 @@ L1: r13 = load_mem r12 :: native_int* keep_alive source r14 = r13 << 1 - r15 = r11 < r14 :: signed + r15 = int_lt r11, r14 if r15 goto L2 else goto L4 :: bool L2: r16 = CPyList_GetItemUnsafe(source, r11) @@ -335,7 +335,7 @@ L1: r5 = CPyStr_Size_size_t(source) r6 = r5 >= 0 :: signed r7 = r5 << 1 - r8 = r4 < r7 :: signed + r8 = int_lt r4, r7 if r8 goto L2 else goto L4 :: bool L2: r9 = CPyStr_GetItem(source, r4) @@ -391,7 +391,7 @@ L1: r5 = load_mem r4 :: native_int* keep_alive source r6 = r5 << 1 - r7 = r3 < r6 :: signed + r7 = int_lt r3, r6 if r7 goto L2 else goto L4 :: bool L2: r8 = CPySequenceTuple_GetItem(source, r3) diff --git a/mypyc/test-data/lowering-int.test b/mypyc/test-data/lowering-int.test index 8c813563d0e6..e7df944c4458 100644 --- a/mypyc/test-data/lowering-int.test +++ b/mypyc/test-data/lowering-int.test @@ -13,13 +13,13 @@ def f(x, y): r1, r2, r3 :: bit L0: r0 = x & 1 - r1 = r0 == 0 + r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: - r2 = x == y + r2 = CPyTagged_IsEq_(x, y) if r2 goto L3 else goto L4 :: bool L2: - r3 = CPyTagged_IsEq_(x, y) + r3 = x == y if r3 goto L3 else goto L4 :: bool L3: return 2 @@ -39,14 +39,14 @@ def f(x, y): r1, r2, r3, r4 :: bit L0: r0 = x & 1 - r1 = r0 == 0 + r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: - r2 = x != y - if r2 goto L3 else goto L4 :: bool + r2 = CPyTagged_IsEq_(x, y) + r3 = r2 ^ 1 + if r3 goto L3 else goto L4 :: bool L2: - r3 = CPyTagged_IsEq_(x, y) - r4 = r3 ^ 1 + r4 = x != y if r4 goto L3 else goto L4 :: bool L3: return 2 @@ -113,14 +113,265 @@ def f(x, y): r4 :: bit L0: r0 = x & 1 - r1 = r0 == 0 + r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: - r2 = x == y + r2 = CPyTagged_IsEq_(x, y) r3 = r2 goto L3 L2: - r4 = CPyTagged_IsEq_(x, y) + r4 = x == y r3 = r4 L3: return r3 + +[case testLowerIntLt] +def f(x: int, y: int) -> int: + if x < y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(x, y) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = x < y :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntLe] +def f(x: int, y: int) -> int: + if x <= y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5, r6 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(y, x) + r5 = r4 ^ 1 + if r5 goto L4 else goto L5 :: bool +L3: + r6 = x <= y :: signed + if r6 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntGt] +def f(x: int, y: int) -> int: + if x > y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(y, x) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = x > y :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntGe] +def f(x: int, y: int) -> int: + if x >= y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5, r6 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(x, y) + r5 = r4 ^ 1 + if r5 goto L4 else goto L5 :: bool +L3: + r6 = x >= y :: signed + if r6 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntLtShort] +def both() -> int: + if 3 < 5: + return 1 + else: + return 2 + +def rhs_only(x: int) -> int: + if x < 5: + return 1 + else: + return 2 + +def lhs_only(x: int) -> int: + if 5 < x: + return 1 + else: + return 2 +[out] +def both(): + r0 :: bit +L0: + r0 = 6 < 10 :: signed + if r0 goto L1 else goto L2 :: bool +L1: + return 2 +L2: + return 4 +def rhs_only(x): + x :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = 10 & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(x, 10) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = x < 10 :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 +def lhs_only(x): + x :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = 10 & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = x & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(10, x) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = 10 < x :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntForLoop] +from __future__ import annotations + +def f(l: list[int]) -> None: + for x in l: + pass +[out] +def f(l): + l :: list + r0 :: short_int + r1 :: ptr + r2 :: native_int + r3 :: short_int + r4 :: bit + r5 :: object + r6, x :: int + r7 :: short_int + r8 :: None +L0: + r0 = 0 +L1: + r1 = get_element_ptr l ob_size :: PyVarObject + r2 = load_mem r1 :: native_int* + r3 = r2 << 1 + r4 = r0 < r3 :: signed + if r4 goto L2 else goto L5 :: bool +L2: + r5 = CPyList_GetItemUnsafe(l, r0) + r6 = unbox(int, r5) + dec_ref r5 + if is_error(r6) goto L6 (error at f:4) else goto L3 +L3: + x = r6 + dec_ref x :: int +L4: + r7 = r0 + 2 + r0 = r7 + goto L1 +L5: + return 1 +L6: + r8 = :: None + return r8 diff --git a/mypyc/test-data/refcount.test b/mypyc/test-data/refcount.test index df980af8a7c7..3021381abded 100644 --- a/mypyc/test-data/refcount.test +++ b/mypyc/test-data/refcount.test @@ -452,41 +452,27 @@ def f(a: int) -> int: [out] def f(a): a, sum, i :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6, r7 :: int + r0 :: bit + r1, r2 :: int L0: sum = 0 i = 0 L1: - r0 = i & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_le i, a + if r0 goto L2 else goto L4 :: bool L2: - r2 = a & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(a, i) - if r4 goto L7 else goto L5 :: bool -L4: - r5 = i <= a :: signed - if r5 goto L5 else goto L7 :: bool -L5: - r6 = CPyTagged_Add(sum, i) + r1 = CPyTagged_Add(sum, i) dec_ref sum :: int - sum = r6 - r7 = CPyTagged_Add(i, 2) + sum = r1 + r2 = CPyTagged_Add(i, 2) dec_ref i :: int - i = r7 + i = r2 goto L1 -L6: +L3: return sum -L7: +L4: dec_ref i :: int - goto L6 + goto L3 [case testCall] def f(a: int) -> int: @@ -1357,30 +1343,12 @@ class C: def add(c): c :: __main__.C r0, r1 :: int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit + r2 :: bit L0: r0 = borrow c.x r1 = borrow c.y - r2 = r0 & 1 - r3 = r2 == 0 - r4 = r1 & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool -L1: - r7 = r0 < r1 :: signed - r8 = r7 - goto L3 -L2: - r9 = CPyTagged_IsLt_(r0, r1) - r8 = r9 -L3: - return r8 + r2 = int_lt r0, r1 + return r2 [case testBorrowIntCompareFinal] from typing_extensions import Final