@@ -2570,26 +2570,35 @@ def _never_equal_to_none(self, typ: RType) -> bool:
25702570 def _translate_fast_optional_eq_cmp (
25712571 self , lreg : Value , rreg : Value , expr_op : str , line : int
25722572 ) -> Value :
2573+ """Generate eq/ne fast path between 'X | None' and ('X | None' or X).
2574+
2575+ Assume 'X' never compares equal to None.
2576+ """
25732577 if not isinstance (lreg .type , RUnion ):
25742578 lreg , rreg = rreg , lreg
25752579 value_typ = optional_value_type (lreg .type )
25762580 assert value_typ
25772581 res = Register (bool_rprimitive )
2582+
2583+ # Fast path: left value is None?
25782584 cmp = self .add (ComparisonOp (lreg , self .none_object (), ComparisonOp .EQ , line ))
25792585 l_none = BasicBlock ()
25802586 l_not_none = BasicBlock ()
25812587 out = BasicBlock ()
25822588 self .add (Branch (cmp , l_none , l_not_none , Branch .BOOL ))
25832589 self .activate_block (l_none )
25842590 if not isinstance (rreg .type , RUnion ):
2585- self .add (Assign (res , self .false ()))
2591+ val = self .false () if expr_op == "==" else self .true ()
2592+ self .add (Assign (res , val ))
25862593 else :
25872594 op = ComparisonOp .EQ if expr_op == "==" else ComparisonOp .NEQ
25882595 cmp = self .add (ComparisonOp (rreg , self .none_object (), op , line ))
25892596 self .add (Assign (res , cmp ))
25902597 self .goto (out )
2598+
25912599 self .activate_block (l_not_none )
25922600 if not isinstance (rreg .type , RUnion ):
2601+ # Both operands are known to be not None, perform specialized comparison
25932602 eq = self .translate_eq_cmp (
25942603 self .unbox_or_cast (lreg , value_typ , line , can_borrow = True , unchecked = True ),
25952604 rreg ,
@@ -2601,12 +2610,16 @@ def _translate_fast_optional_eq_cmp(
26012610 else :
26022611 r_none = BasicBlock ()
26032612 r_not_none = BasicBlock ()
2613+ # Fast path: eight value is None?
26042614 cmp = self .add (ComparisonOp (rreg , self .none_object (), ComparisonOp .EQ , line ))
26052615 self .add (Branch (cmp , r_none , r_not_none , Branch .BOOL ))
26062616 self .activate_block (r_none )
2617+ # None vs not-None
2618+ val = self .false () if expr_op == "==" else self .true ()
26072619 self .add (Assign (res , self .false ()))
26082620 self .goto (out )
26092621 self .activate_block (r_not_none )
2622+ # Both operands are known to be not None, perform specialized comparison
26102623 eq = self .translate_eq_cmp (
26112624 self .unbox_or_cast (lreg , value_typ , line , can_borrow = True , unchecked = True ),
26122625 self .unbox_or_cast (rreg , value_typ , line , can_borrow = True , unchecked = True ),
0 commit comments