@@ -1315,13 +1315,6 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value:
13151315 return self .compare_strings (lreg , rreg , op , line )
13161316 if is_bytes_rprimitive (ltype ) and is_bytes_rprimitive (rtype ) and op in ("==" , "!=" ):
13171317 return self .compare_bytes (lreg , rreg , op , line )
1318- if (
1319- is_tagged (ltype )
1320- and is_tagged (rtype )
1321- and op in int_comparison_op_mapping
1322- and op not in ("==" , "!=" )
1323- ):
1324- return self .compare_tagged (lreg , rreg , op , line )
13251318 if is_bool_rprimitive (ltype ) and is_bool_rprimitive (rtype ) and op in BOOL_BINARY_OPS :
13261319 if op in ComparisonOp .signed_ops :
13271320 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:
13841377 if is_fixed_width_rtype (lreg .type ):
13851378 return self .comparison_op (lreg , rreg , op_id , line )
13861379
1387- # Mixed int comparisons
1388- if op in ("==" , "!=" ):
1389- pass # TODO: Do we need anything here?
1390- elif op in op in int_comparison_op_mapping :
1391- if is_tagged (ltype ) and is_subtype (rtype , ltype ):
1392- rreg = self .coerce (rreg , short_int_rprimitive , line )
1393- return self .compare_tagged (lreg , rreg , op , line )
1394- if is_tagged (rtype ) and is_subtype (ltype , rtype ):
1395- lreg = self .coerce (lreg , short_int_rprimitive , line )
1396- return self .compare_tagged (lreg , rreg , op , line )
13971380 if is_float_rprimitive (ltype ) or is_float_rprimitive (rtype ):
13981381 if isinstance (lreg , Integer ):
13991382 lreg = Float (float (lreg .numeric_value ()))
@@ -1445,18 +1428,16 @@ def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value:
14451428 op_type , c_func_desc , negate_result , swap_op = int_comparison_op_mapping [op ]
14461429 result = Register (bool_rprimitive )
14471430 short_int_block , int_block , out = BasicBlock (), BasicBlock (), BasicBlock ()
1448- check_lhs = self .check_tagged_short_int (lhs , line )
1431+ check_lhs = self .check_tagged_short_int (lhs , line , negated = True )
14491432 if op in ("==" , "!=" ):
1450- check = check_lhs
1433+ self . add ( Branch ( check_lhs , int_block , short_int_block , Branch . BOOL ))
14511434 else :
14521435 # for non-equality logical ops (less/greater than, etc.), need to check both sides
1453- check_rhs = self .check_tagged_short_int (rhs , line )
1454- check = self .int_op (bit_rprimitive , check_lhs , check_rhs , IntOp .AND , line )
1455- self .add (Branch (check , short_int_block , int_block , Branch .BOOL ))
1456- self .activate_block (short_int_block )
1457- eq = self .comparison_op (lhs , rhs , op_type , line )
1458- self .add (Assign (result , eq , line ))
1459- self .goto (out )
1436+ short_lhs = BasicBlock ()
1437+ self .add (Branch (check_lhs , int_block , short_lhs , Branch .BOOL ))
1438+ self .activate_block (short_lhs )
1439+ check_rhs = self .check_tagged_short_int (rhs , line , negated = True )
1440+ self .add (Branch (check_rhs , int_block , short_int_block , Branch .BOOL ))
14601441 self .activate_block (int_block )
14611442 if swap_op :
14621443 args = [rhs , lhs ]
@@ -1469,62 +1450,12 @@ def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value:
14691450 else :
14701451 call_result = call
14711452 self .add (Assign (result , call_result , line ))
1472- self .goto_and_activate (out )
1473- return result
1474-
1475- def compare_tagged_condition (
1476- self , lhs : Value , rhs : Value , op : str , true : BasicBlock , false : BasicBlock , line : int
1477- ) -> None :
1478- """Compare two tagged integers using given operator (conditional context).
1479-
1480- Assume lhs and rhs are tagged integers.
1481-
1482- Args:
1483- lhs: Left operand
1484- rhs: Right operand
1485- op: Operation, one of '==', '!=', '<', '<=', '>', '<='
1486- true: Branch target if comparison is true
1487- false: Branch target if comparison is false
1488- """
1489- is_eq = op in ("==" , "!=" )
1490- if (is_short_int_rprimitive (lhs .type ) and is_short_int_rprimitive (rhs .type )) or (
1491- is_eq and (is_short_int_rprimitive (lhs .type ) or is_short_int_rprimitive (rhs .type ))
1492- ):
1493- # We can skip the tag check
1494- check = self .comparison_op (lhs , rhs , int_comparison_op_mapping [op ][0 ], line )
1495- self .flush_keep_alives ()
1496- self .add (Branch (check , true , false , Branch .BOOL ))
1497- return
1498- op_type , c_func_desc , negate_result , swap_op = int_comparison_op_mapping [op ]
1499- int_block , short_int_block = BasicBlock (), BasicBlock ()
1500- check_lhs = self .check_tagged_short_int (lhs , line , negated = True )
1501- if is_eq or is_short_int_rprimitive (rhs .type ):
1502- self .flush_keep_alives ()
1503- self .add (Branch (check_lhs , int_block , short_int_block , Branch .BOOL ))
1504- else :
1505- # For non-equality logical ops (less/greater than, etc.), need to check both sides
1506- rhs_block = BasicBlock ()
1507- self .add (Branch (check_lhs , int_block , rhs_block , Branch .BOOL ))
1508- self .activate_block (rhs_block )
1509- check_rhs = self .check_tagged_short_int (rhs , line , negated = True )
1510- self .flush_keep_alives ()
1511- self .add (Branch (check_rhs , int_block , short_int_block , Branch .BOOL ))
1512- # Arbitrary integers (slow path)
1513- self .activate_block (int_block )
1514- if swap_op :
1515- args = [rhs , lhs ]
1516- else :
1517- args = [lhs , rhs ]
1518- call = self .call_c (c_func_desc , args , line )
1519- if negate_result :
1520- self .add (Branch (call , false , true , Branch .BOOL ))
1521- else :
1522- self .flush_keep_alives ()
1523- self .add (Branch (call , true , false , Branch .BOOL ))
1524- # Short integers (fast path)
1453+ self .goto (out )
15251454 self .activate_block (short_int_block )
15261455 eq = self .comparison_op (lhs , rhs , op_type , line )
1527- self .add (Branch (eq , true , false , Branch .BOOL ))
1456+ self .add (Assign (result , eq , line ))
1457+ self .goto_and_activate (out )
1458+ return result
15281459
15291460 def compare_strings (self , lhs : Value , rhs : Value , op : str , line : int ) -> Value :
15301461 """Compare two strings"""
@@ -2309,7 +2240,8 @@ def builtin_len(self, val: Value, line: int, use_pyssize_t: bool = False) -> Val
23092240 length = self .gen_method_call (val , "__len__" , [], int_rprimitive , line )
23102241 length = self .coerce (length , int_rprimitive , line )
23112242 ok , fail = BasicBlock (), BasicBlock ()
2312- self .compare_tagged_condition (length , Integer (0 ), ">=" , ok , fail , line )
2243+ cond = self .binary_op (length , Integer (0 ), ">=" , line )
2244+ self .add_bool_branch (cond , ok , fail )
23132245 self .activate_block (fail )
23142246 self .add (
23152247 RaiseStandardError (
0 commit comments