-- Test cases for converting high-level IR to lower-level IR (lowering).

[case testLowerIntEq]
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, r2, r3 :: bit
L0:
    r0 = x & 1
    r1 = r0 != 0
    if r1 goto L1 else goto L2 :: bool
L1:
    r2 = CPyTagged_IsEq_(x, y)
    if r2 goto L3 else goto L4 :: bool
L2:
    r3 = x == y
    if r3 goto L3 else goto L4 :: bool
L3:
    return 2
L4:
    return 4

[case testLowerIntNe]
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, r2, r3, r4 :: bit
L0:
    r0 = x & 1
    r1 = r0 != 0
    if r1 goto L1 else goto L2 :: bool
L1:
    r2 = CPyTagged_IsEq_(x, y)
    r3 = r2 ^ 1
    if r3 goto L3 else goto L4 :: bool
L2:
    r4 = x != y
    if r4 goto L3 else goto L4 :: bool
L3:
    return 2
L4:
    return 4

[case testLowerIntEqWithConstant]
def f(x: int, y: int) -> int:
    if x == 2:
        return 1
    elif -1 == x:
        return 2
    return 3
[out]
def f(x, y):
    x, y :: int
    r0, r1 :: bit
L0:
    r0 = x == 4
    if r0 goto L1 else goto L2 :: bool
L1:
    return 2
L2:
    r1 = -2 == x
    if r1 goto L3 else goto L4 :: bool
L3:
    return 4
L4:
    return 6

[case testLowerIntNeWithConstant]
def f(x: int, y: int) -> int:
    if x != 2:
        return 1
    elif -1 != x:
        return 2
    return 3
[out]
def f(x, y):
    x, y :: int
    r0, r1 :: bit
L0:
    r0 = x != 4
    if r0 goto L1 else goto L2 :: bool
L1:
    return 2
L2:
    r1 = -2 != x
    if r1 goto L3 else goto L4 :: bool
L3:
    return 4
L4:
    return 6

[case testLowerIntEqValueContext]
def f(x: int, y: int) -> bool:
    return x == y
[out]
def f(x, y):
    x, y :: int
    r0 :: native_int
    r1, r2 :: bit
    r3 :: bool
    r4 :: bit
L0:
    r0 = x & 1
    r1 = r0 != 0
    if r1 goto L1 else goto L2 :: bool
L1:
    r2 = CPyTagged_IsEq_(x, y)
    r3 = r2
    goto L3
L2:
    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 = <error> :: None
    return r8
