diff --git a/mypyc/ir/ops.py b/mypyc/ir/ops.py index 896ba3ac091c..6e186c4ef0fc 100644 --- a/mypyc/ir/ops.py +++ b/mypyc/ir/ops.py @@ -625,7 +625,7 @@ def __init__( assert error_kind == ERR_NEVER def __repr__(self) -> str: - return f"" + return f"" class PrimitiveOp(RegisterOp): diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index df73f8481751..a5a524b25af0 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -1601,8 +1601,8 @@ def unary_op(self, value: Value, expr_op: str, line: int) -> Value: result = self.dunder_op(value, None, expr_op, line) if result is not None: return result - call_c_ops_candidates = unary_ops.get(expr_op, []) - target = self.matching_call_c(call_c_ops_candidates, [value], line) + primitive_ops_candidates = unary_ops.get(expr_op, []) + target = self.matching_primitive_op(primitive_ops_candidates, [value], line) assert target, "Unsupported unary operation: %s" % expr_op return target diff --git a/mypyc/primitives/int_ops.py b/mypyc/primitives/int_ops.py index 2eff233403f4..657578d20046 100644 --- a/mypyc/primitives/int_ops.py +++ b/mypyc/primitives/int_ops.py @@ -31,14 +31,7 @@ str_rprimitive, void_rtype, ) -from mypyc.primitives.registry import ( - CFunctionDescription, - binary_op, - custom_op, - function_op, - load_address_op, - unary_op, -) +from mypyc.primitives.registry import binary_op, custom_op, function_op, load_address_op, unary_op # Constructors for builtins.int and native int types have the same behavior. In # interpreted mode, native int types are just aliases to 'int'. @@ -176,7 +169,7 @@ def int_binary_op( int_binary_op("<<=", "CPyTagged_Lshift", error_kind=ERR_MAGIC) -def int_unary_op(name: str, c_function_name: str) -> CFunctionDescription: +def int_unary_op(name: str, c_function_name: str) -> PrimitiveDescription: return unary_op( name=name, arg_type=int_rprimitive, diff --git a/mypyc/primitives/registry.py b/mypyc/primitives/registry.py index 25ad83be14f5..26faabc0c1e2 100644 --- a/mypyc/primitives/registry.py +++ b/mypyc/primitives/registry.py @@ -79,8 +79,8 @@ class LoadAddressDescription(NamedTuple): # Primitive ops for binary operations binary_ops: dict[str, list[PrimitiveDescription]] = {} -# CallC op for unary ops -unary_ops: dict[str, list[CFunctionDescription]] = {} +# Primitive ops for unary ops +unary_ops: dict[str, list[PrimitiveDescription]] = {} builtin_names: dict[str, tuple[RType, str]] = {} @@ -327,8 +327,8 @@ def unary_op( is_borrowed: bool = False, priority: int = 1, is_pure: bool = False, -) -> CFunctionDescription: - """Define a c function call op for an unary operation. +) -> PrimitiveDescription: + """Define a primitive op for an unary operation. This will be automatically generated by matching against the AST. @@ -338,19 +338,19 @@ def unary_op( if extra_int_constants is None: extra_int_constants = [] ops = unary_ops.setdefault(name, []) - desc = CFunctionDescription( + desc = PrimitiveDescription( name, [arg_type], return_type, - None, - truncated_type, - c_function_name, - error_kind, - steals, - is_borrowed, - ordering, - extra_int_constants, - priority, + var_arg_type=None, + truncated_type=truncated_type, + c_function_name=c_function_name, + error_kind=error_kind, + steals=steals, + is_borrowed=is_borrowed, + ordering=ordering, + extra_int_constants=extra_int_constants, + priority=priority, is_pure=is_pure, ) ops.append(desc) diff --git a/mypyc/test-data/irbuild-int.test b/mypyc/test-data/irbuild-int.test index b1a712103e70..9082cc0136d9 100644 --- a/mypyc/test-data/irbuild-int.test +++ b/mypyc/test-data/irbuild-int.test @@ -182,13 +182,31 @@ def int_to_int(n): L0: return n -[case testIntUnaryPlus] +[case testIntUnaryOps] +def unary_minus(n: int) -> int: + x = -n + return x def unary_plus(n: int) -> int: x = +n return x +def unary_invert(n: int) -> int: + x = ~n + return x [out] +def unary_minus(n): + n, r0, x :: int +L0: + r0 = CPyTagged_Negate(n) + x = r0 + return x def unary_plus(n): n, x :: int L0: x = n return x +def unary_invert(n): + n, r0, x :: int +L0: + r0 = CPyTagged_Invert(n) + x = r0 + return x diff --git a/mypyc/test/test_cheader.py b/mypyc/test/test_cheader.py index 08b5a4648ca5..9c09f14e93dd 100644 --- a/mypyc/test/test_cheader.py +++ b/mypyc/test/test_cheader.py @@ -26,14 +26,18 @@ def check_name(name: str) -> None: rf"\b{name}\b", header ), f'"{name}" is used in mypyc.primitives but not declared in CPy.h' - for old_values in [registry.method_call_ops.values(), registry.unary_ops.values()]: + for old_values in [registry.method_call_ops.values()]: for old_ops in old_values: if isinstance(old_ops, CFunctionDescription): old_ops = [old_ops] for old_op in old_ops: check_name(old_op.c_function_name) - for values in [registry.binary_ops.values(), registry.function_ops.values()]: + for values in [ + registry.binary_ops.values(), + registry.unary_ops.values(), + registry.function_ops.values(), + ]: for ops in values: if isinstance(ops, PrimitiveDescription): ops = [ops] diff --git a/mypyc/test/test_emitfunc.py b/mypyc/test/test_emitfunc.py index 273ba409fac2..b97ad78d6970 100644 --- a/mypyc/test/test_emitfunc.py +++ b/mypyc/test/test_emitfunc.py @@ -154,6 +154,7 @@ def test_int_sub(self) -> None: ) def test_int_neg(self) -> None: + assert int_neg_op.c_function_name is not None self.assert_emit( CallC( int_neg_op.c_function_name,