Skip to content

Commit 7bd9cd8

Browse files
committed
Fix !=
1 parent eba7d3e commit 7bd9cd8

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

mypyc/irbuild/ll_builder.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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),

mypyc/test-data/irbuild-str.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ L3:
745745
from typing import Optional
746746

747747
def non_opt_opt(x: bytes, y: Optional[bytes]) -> bool:
748-
return x == y
748+
return x != y
749749
[out]
750750
def non_opt_opt(x, y):
751751
x :: bytes
@@ -761,13 +761,13 @@ L0:
761761
r1 = y == r0
762762
if r1 goto L1 else goto L2 :: bool
763763
L1:
764-
r2 = 0
764+
r2 = 1
765765
goto L3
766766
L2:
767767
r3 = unchecked borrow cast(bytes, y)
768768
r4 = CPyBytes_Compare(r3, x)
769769
r5 = r4 >= 0 :: signed
770-
r6 = r4 == 1
770+
r6 = r4 != 1
771771
r2 = r6
772772
L3:
773773
keep_alive y

0 commit comments

Comments
 (0)