# Generated by ruleopt/generate.py, don't edit!

import sys
from rpython.jit.metainterp.history import ConstInt
from rpython.jit.metainterp.optimizeopt.util import (
    get_box_replacement)
from rpython.jit.metainterp.resoperation import rop

from rpython.rlib.rarithmetic import LONG_BIT, r_uint, intmask, ovfcheck, uint_mul_high, highest_bit
MAXINT = sys.maxint
MININT = -sys.maxint - 1


class OptIntAutoGenerated(object):
    def _eq(self, box1, bound1, box2, bound2):
        if box1 is box2: return True
        if bound1.is_constant() and bound2.is_constant() and bound1.lower == bound2.lower: return True
        return False
    _all_rules_fired = []
    _rule_names_int_add = ['add_reassoc_consts', 'add_zero', 'add_sub_x_c_c', 'add_sub_c_x_c']
    _rule_fired_int_add = [0] * 4
    _all_rules_fired.append(('int_add', _rule_names_int_add, _rule_fired_int_add))
    def optimize_INT_ADD(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # add_zero: int_add(0, x) => x
            if C_arg_0 == 0:
                self.make_equal_to(op, arg_1)
                self._rule_fired_int_add[1] += 1
                return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # add_zero: int_add(x, 0) => x
            if C_arg_1 == 0:
                self.make_equal_to(op, arg_0)
                self._rule_fired_int_add[1] += 1
                return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            arg_1_int_add = self.optimizer.as_operation(arg_1, rop.INT_ADD)
            if arg_1_int_add is not None:
                arg_1_0 = get_box_replacement(arg_1_int_add.getarg(0))
                b_arg_1_0 = self.getintbound(arg_1_0)
                arg_1_1 = get_box_replacement(arg_1_int_add.getarg(1))
                b_arg_1_1 = self.getintbound(arg_1_1)
                if b_arg_1_0.is_constant():
                    C_arg_1_0 = b_arg_1_0.get_constant_int()
                    # add_reassoc_consts: int_add(C2, int_add(C1, x)) => int_add(x, C)
                    C = intmask(r_uint(C_arg_1_0) + r_uint(C_arg_0))
                    newop = self.replace_op_with(op, rop.INT_ADD, args=[arg_1_1, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_add[0] += 1
                    return
                if b_arg_1_1.is_constant():
                    C_arg_1_1 = b_arg_1_1.get_constant_int()
                    # add_reassoc_consts: int_add(C2, int_add(x, C1)) => int_add(x, C)
                    C = intmask(r_uint(C_arg_1_1) + r_uint(C_arg_0))
                    newop = self.replace_op_with(op, rop.INT_ADD, args=[arg_1_0, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_add[0] += 1
                    return
            else:
                arg_1_int_sub = self.optimizer.as_operation(arg_1, rop.INT_SUB)
                if arg_1_int_sub is not None:
                    arg_1_0 = get_box_replacement(arg_1_int_sub.getarg(0))
                    b_arg_1_0 = self.getintbound(arg_1_0)
                    arg_1_1 = get_box_replacement(arg_1_int_sub.getarg(1))
                    b_arg_1_1 = self.getintbound(arg_1_1)
                    if b_arg_1_0.is_constant():
                        C_arg_1_0 = b_arg_1_0.get_constant_int()
                        # add_sub_c_x_c: int_add(C2, int_sub(C1, x)) => int_sub(C, x)
                        C = intmask(r_uint(C_arg_1_0) + r_uint(C_arg_0))
                        newop = self.replace_op_with(op, rop.INT_SUB, args=[ConstInt(C), arg_1_1])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_add[3] += 1
                        return
                    if b_arg_1_1.is_constant():
                        C_arg_1_1 = b_arg_1_1.get_constant_int()
                        # add_sub_x_c_c: int_add(C2, int_sub(x, C1)) => int_add(x, C)
                        C = intmask(r_uint(C_arg_0) - r_uint(C_arg_1_1))
                        newop = self.replace_op_with(op, rop.INT_ADD, args=[arg_1_0, ConstInt(C)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_add[2] += 1
                        return
        else:
            arg_0_int_add = self.optimizer.as_operation(arg_0, rop.INT_ADD)
            if arg_0_int_add is not None:
                arg_0_0 = get_box_replacement(arg_0_int_add.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_add.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                if b_arg_0_0.is_constant():
                    C_arg_0_0 = b_arg_0_0.get_constant_int()
                    if b_arg_1.is_constant():
                        C_arg_1 = b_arg_1.get_constant_int()
                        # add_reassoc_consts: int_add(int_add(C1, x), C2) => int_add(x, C)
                        C = intmask(r_uint(C_arg_0_0) + r_uint(C_arg_1))
                        newop = self.replace_op_with(op, rop.INT_ADD, args=[arg_0_1, ConstInt(C)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_add[0] += 1
                        return
                if b_arg_0_1.is_constant():
                    C_arg_0_1 = b_arg_0_1.get_constant_int()
                    if b_arg_1.is_constant():
                        C_arg_1 = b_arg_1.get_constant_int()
                        # add_reassoc_consts: int_add(int_add(x, C1), C2) => int_add(x, C)
                        C = intmask(r_uint(C_arg_0_1) + r_uint(C_arg_1))
                        newop = self.replace_op_with(op, rop.INT_ADD, args=[arg_0_0, ConstInt(C)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_add[0] += 1
                        return
            else:
                arg_0_int_sub = self.optimizer.as_operation(arg_0, rop.INT_SUB)
                if arg_0_int_sub is not None:
                    arg_0_0 = get_box_replacement(arg_0_int_sub.getarg(0))
                    b_arg_0_0 = self.getintbound(arg_0_0)
                    arg_0_1 = get_box_replacement(arg_0_int_sub.getarg(1))
                    b_arg_0_1 = self.getintbound(arg_0_1)
                    if b_arg_0_0.is_constant():
                        C_arg_0_0 = b_arg_0_0.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # add_sub_c_x_c: int_add(int_sub(C1, x), C2) => int_sub(C, x)
                            C = intmask(r_uint(C_arg_0_0) + r_uint(C_arg_1))
                            newop = self.replace_op_with(op, rop.INT_SUB, args=[ConstInt(C), arg_0_1])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_add[3] += 1
                            return
                    if b_arg_0_1.is_constant():
                        C_arg_0_1 = b_arg_0_1.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # add_sub_x_c_c: int_add(int_sub(x, C1), C2) => int_add(x, C)
                            C = intmask(r_uint(C_arg_1) - r_uint(C_arg_0_1))
                            newop = self.replace_op_with(op, rop.INT_ADD, args=[arg_0_0, ConstInt(C)])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_add[2] += 1
                            return
        return self.emit(op)
    _rule_names_int_sub = ['sub_zero', 'sub_from_zero', 'sub_x_x', 'sub_add_consts', 'sub_add', 'sub_add_neg', 'sub_sub_left_x_c_c', 'sub_sub_left_c_x_c', 'sub_xor_x_y_y', 'sub_or_x_y_y', 'sub_invert_one']
    _rule_fired_int_sub = [0] * 11
    _all_rules_fired.append(('int_sub', _rule_names_int_sub, _rule_fired_int_sub))
    def optimize_INT_SUB(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        # sub_x_x: int_sub(x, x) => 0
        if self._eq(arg_1, b_arg_1, arg_0, b_arg_0):
            self.make_constant_int(op, 0)
            self._rule_fired_int_sub[2] += 1
            return
        arg_0_int_add = self.optimizer.as_operation(arg_0, rop.INT_ADD)
        if arg_0_int_add is not None:
            arg_0_0 = get_box_replacement(arg_0_int_add.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            arg_0_1 = get_box_replacement(arg_0_int_add.getarg(1))
            b_arg_0_1 = self.getintbound(arg_0_1)
            # sub_add: int_sub(int_add(x, y), y) => x
            if self._eq(arg_1, b_arg_1, arg_0_1, b_arg_0_1):
                self.make_equal_to(op, arg_0_0)
                self._rule_fired_int_sub[4] += 1
                return
            # sub_add: int_sub(int_add(y, x), y) => x
            if self._eq(arg_1, b_arg_1, arg_0_0, b_arg_0_0):
                self.make_equal_to(op, arg_0_1)
                self._rule_fired_int_sub[4] += 1
                return
        else:
            arg_0_int_or = self.optimizer.as_operation(arg_0, rop.INT_OR)
            if arg_0_int_or is not None:
                arg_0_0 = get_box_replacement(arg_0_int_or.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_or.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                # sub_or_x_y_y: int_sub(int_or(x, y), y) => x
                if self._eq(arg_1, b_arg_1, arg_0_1, b_arg_0_1):
                    if b_arg_0_0.and_bound(b_arg_0_1).known_eq_const(0):
                        self.make_equal_to(op, arg_0_0)
                        self._rule_fired_int_sub[9] += 1
                        return
                # sub_or_x_y_y: int_sub(int_or(y, x), y) => x
                if self._eq(arg_1, b_arg_1, arg_0_0, b_arg_0_0):
                    if b_arg_0_1.and_bound(b_arg_0_0).known_eq_const(0):
                        self.make_equal_to(op, arg_0_1)
                        self._rule_fired_int_sub[9] += 1
                        return
            else:
                arg_0_int_xor = self.optimizer.as_operation(arg_0, rop.INT_XOR)
                if arg_0_int_xor is not None:
                    arg_0_0 = get_box_replacement(arg_0_int_xor.getarg(0))
                    b_arg_0_0 = self.getintbound(arg_0_0)
                    arg_0_1 = get_box_replacement(arg_0_int_xor.getarg(1))
                    b_arg_0_1 = self.getintbound(arg_0_1)
                    # sub_xor_x_y_y: int_sub(int_xor(x, y), y) => x
                    if self._eq(arg_1, b_arg_1, arg_0_1, b_arg_0_1):
                        if b_arg_0_0.and_bound(b_arg_0_1).known_eq_const(0):
                            self.make_equal_to(op, arg_0_0)
                            self._rule_fired_int_sub[8] += 1
                            return
                    # sub_xor_x_y_y: int_sub(int_xor(y, x), y) => x
                    if self._eq(arg_1, b_arg_1, arg_0_0, b_arg_0_0):
                        if b_arg_0_1.and_bound(b_arg_0_0).known_eq_const(0):
                            self.make_equal_to(op, arg_0_1)
                            self._rule_fired_int_sub[8] += 1
                            return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # sub_zero: int_sub(x, 0) => x
            if C_arg_1 == 0:
                self.make_equal_to(op, arg_0)
                self._rule_fired_int_sub[0] += 1
                return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # sub_from_zero: int_sub(0, x) => int_neg(x)
            if C_arg_0 == 0:
                newop = self.replace_op_with(op, rop.INT_NEG, args=[arg_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_sub[1] += 1
                return
        else:
            arg_0_int_invert = self.optimizer.as_operation(arg_0, rop.INT_INVERT)
            if arg_0_int_invert is not None:
                arg_0_0 = get_box_replacement(arg_0_int_invert.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                if b_arg_1.is_constant():
                    C_arg_1 = b_arg_1.get_constant_int()
                    # sub_invert_one: int_sub(int_invert(x), -1) => int_neg(x)
                    if C_arg_1 == -1:
                        newop = self.replace_op_with(op, rop.INT_NEG, args=[arg_0_0])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_sub[10] += 1
                        return
            else:
                arg_0_int_add = self.optimizer.as_operation(arg_0, rop.INT_ADD)
                if arg_0_int_add is not None:
                    arg_0_0 = get_box_replacement(arg_0_int_add.getarg(0))
                    b_arg_0_0 = self.getintbound(arg_0_0)
                    arg_0_1 = get_box_replacement(arg_0_int_add.getarg(1))
                    b_arg_0_1 = self.getintbound(arg_0_1)
                    if b_arg_0_0.is_constant():
                        C_arg_0_0 = b_arg_0_0.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # sub_add_consts: int_sub(int_add(C1, x), C2) => int_sub(x, C)
                            C = intmask(r_uint(C_arg_1) - r_uint(C_arg_0_0))
                            newop = self.replace_op_with(op, rop.INT_SUB, args=[arg_0_1, ConstInt(C)])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_sub[3] += 1
                            return
                    if b_arg_0_1.is_constant():
                        C_arg_0_1 = b_arg_0_1.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # sub_add_consts: int_sub(int_add(x, C1), C2) => int_sub(x, C)
                            C = intmask(r_uint(C_arg_1) - r_uint(C_arg_0_1))
                            newop = self.replace_op_with(op, rop.INT_SUB, args=[arg_0_0, ConstInt(C)])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_sub[3] += 1
                            return
                else:
                    arg_0_int_sub = self.optimizer.as_operation(arg_0, rop.INT_SUB)
                    if arg_0_int_sub is not None:
                        arg_0_0 = get_box_replacement(arg_0_int_sub.getarg(0))
                        b_arg_0_0 = self.getintbound(arg_0_0)
                        arg_0_1 = get_box_replacement(arg_0_int_sub.getarg(1))
                        b_arg_0_1 = self.getintbound(arg_0_1)
                        if b_arg_0_0.is_constant():
                            C_arg_0_0 = b_arg_0_0.get_constant_int()
                            if b_arg_1.is_constant():
                                C_arg_1 = b_arg_1.get_constant_int()
                                # sub_sub_left_c_x_c: int_sub(int_sub(C1, x), C2) => int_sub(C, x)
                                C = intmask(r_uint(C_arg_0_0) - r_uint(C_arg_1))
                                newop = self.replace_op_with(op, rop.INT_SUB, args=[ConstInt(C), arg_0_1])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_sub[7] += 1
                                return
                        if b_arg_0_1.is_constant():
                            C_arg_0_1 = b_arg_0_1.get_constant_int()
                            if b_arg_1.is_constant():
                                C_arg_1 = b_arg_1.get_constant_int()
                                # sub_sub_left_x_c_c: int_sub(int_sub(x, C1), C2) => int_sub(x, C)
                                C = intmask(r_uint(C_arg_0_1) + r_uint(C_arg_1))
                                newop = self.replace_op_with(op, rop.INT_SUB, args=[arg_0_0, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_sub[6] += 1
                                return
        arg_1_int_add = self.optimizer.as_operation(arg_1, rop.INT_ADD)
        if arg_1_int_add is not None:
            arg_1_0 = get_box_replacement(arg_1_int_add.getarg(0))
            b_arg_1_0 = self.getintbound(arg_1_0)
            arg_1_1 = get_box_replacement(arg_1_int_add.getarg(1))
            b_arg_1_1 = self.getintbound(arg_1_1)
            # sub_add_neg: int_sub(y, int_add(x, y)) => int_neg(x)
            if self._eq(arg_1_1, b_arg_1_1, arg_0, b_arg_0):
                newop = self.replace_op_with(op, rop.INT_NEG, args=[arg_1_0])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_sub[5] += 1
                return
            # sub_add_neg: int_sub(y, int_add(y, x)) => int_neg(x)
            if self._eq(arg_1_0, b_arg_1_0, arg_0, b_arg_0):
                newop = self.replace_op_with(op, rop.INT_NEG, args=[arg_1_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_sub[5] += 1
                return
        return self.emit(op)
    _rule_names_int_mul = ['mul_zero', 'mul_one', 'mul_minus_one', 'mul_pow2_const', 'mul_lshift']
    _rule_fired_int_mul = [0] * 5
    _all_rules_fired.append(('int_mul', _rule_names_int_mul, _rule_fired_int_mul))
    def optimize_INT_MUL(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # mul_zero: int_mul(0, x) => 0
            if C_arg_0 == 0:
                self.make_constant_int(op, 0)
                self._rule_fired_int_mul[0] += 1
                return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # mul_zero: int_mul(x, 0) => 0
            if C_arg_1 == 0:
                self.make_constant_int(op, 0)
                self._rule_fired_int_mul[0] += 1
                return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # mul_one: int_mul(1, x) => x
            if C_arg_0 == 1:
                self.make_equal_to(op, arg_1)
                self._rule_fired_int_mul[1] += 1
                return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # mul_one: int_mul(x, 1) => x
            if C_arg_1 == 1:
                self.make_equal_to(op, arg_0)
                self._rule_fired_int_mul[1] += 1
                return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # mul_minus_one: int_mul(-1, x) => int_neg(x)
            if C_arg_0 == -1:
                newop = self.replace_op_with(op, rop.INT_NEG, args=[arg_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_mul[2] += 1
                return
            # mul_pow2_const: int_mul(C, x) => int_lshift(x, shift)
            if C_arg_0 > 0 and C_arg_0 & intmask(r_uint(C_arg_0) - r_uint(1)) == 0:
                shift = highest_bit(C_arg_0)
                newop = self.replace_op_with(op, rop.INT_LSHIFT, args=[arg_1, ConstInt(shift)])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_mul[3] += 1
                return
        else:
            arg_0_int_lshift = self.optimizer.as_operation(arg_0, rop.INT_LSHIFT)
            if arg_0_int_lshift is not None:
                arg_0_0 = get_box_replacement(arg_0_int_lshift.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_lshift.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                if b_arg_0_0.is_constant():
                    C_arg_0_0 = b_arg_0_0.get_constant_int()
                    # mul_lshift: int_mul(int_lshift(1, y), x) => int_lshift(x, y)
                    if C_arg_0_0 == 1:
                        if b_arg_0_1.known_ge_const(0) and b_arg_0_1.known_le_const(LONG_BIT):
                            newop = self.replace_op_with(op, rop.INT_LSHIFT, args=[arg_1, arg_0_1])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_mul[4] += 1
                            return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # mul_minus_one: int_mul(x, -1) => int_neg(x)
            if C_arg_1 == -1:
                newop = self.replace_op_with(op, rop.INT_NEG, args=[arg_0])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_mul[2] += 1
                return
            # mul_pow2_const: int_mul(x, C) => int_lshift(x, shift)
            if C_arg_1 > 0 and C_arg_1 & intmask(r_uint(C_arg_1) - r_uint(1)) == 0:
                shift = highest_bit(C_arg_1)
                newop = self.replace_op_with(op, rop.INT_LSHIFT, args=[arg_0, ConstInt(shift)])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_mul[3] += 1
                return
        else:
            arg_1_int_lshift = self.optimizer.as_operation(arg_1, rop.INT_LSHIFT)
            if arg_1_int_lshift is not None:
                arg_1_0 = get_box_replacement(arg_1_int_lshift.getarg(0))
                b_arg_1_0 = self.getintbound(arg_1_0)
                arg_1_1 = get_box_replacement(arg_1_int_lshift.getarg(1))
                b_arg_1_1 = self.getintbound(arg_1_1)
                if b_arg_1_0.is_constant():
                    C_arg_1_0 = b_arg_1_0.get_constant_int()
                    # mul_lshift: int_mul(x, int_lshift(1, y)) => int_lshift(x, y)
                    if C_arg_1_0 == 1:
                        if b_arg_1_1.known_ge_const(0) and b_arg_1_1.known_le_const(LONG_BIT):
                            newop = self.replace_op_with(op, rop.INT_LSHIFT, args=[arg_0, arg_1_1])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_mul[4] += 1
                            return
        return self.emit(op)
    _rule_names_int_and = ['and_x_x', 'and_reassoc_consts', 'and_x_c_in_range', 'and_idempotent', 'and_or', 'and_known_result', 'and_absorb']
    _rule_fired_int_and = [0] * 7
    _all_rules_fired.append(('int_and', _rule_names_int_and, _rule_fired_int_and))
    def optimize_INT_AND(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        # and_known_result: int_and(a, b) => C
        bound = b_arg_0.and_bound(b_arg_1)
        if bound.is_constant():
            C = bound.get_constant_int()
            self.make_equal_to(op, ConstInt(C))
            self._rule_fired_int_and[5] += 1
            return
        # and_known_result: int_and(b, a) => C
        bound = b_arg_1.and_bound(b_arg_0)
        if bound.is_constant():
            C = bound.get_constant_int()
            self.make_equal_to(op, ConstInt(C))
            self._rule_fired_int_and[5] += 1
            return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # and_x_c_in_range: int_and(C, x) => x
            if intmask(b_arg_1.lower) >= 0 and intmask(b_arg_1.upper) <= C_arg_0 & ~intmask(r_uint(C_arg_0) + r_uint(1)):
                self.make_equal_to(op, arg_1)
                self._rule_fired_int_and[2] += 1
                return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # and_x_c_in_range: int_and(x, C) => x
            if intmask(b_arg_0.lower) >= 0 and intmask(b_arg_0.upper) <= C_arg_1 & ~intmask(r_uint(C_arg_1) + r_uint(1)):
                self.make_equal_to(op, arg_0)
                self._rule_fired_int_and[2] += 1
                return
        # and_x_x: int_and(a, a) => a
        if self._eq(arg_1, b_arg_1, arg_0, b_arg_0):
            self.make_equal_to(op, arg_0)
            self._rule_fired_int_and[0] += 1
            return
        # and_idempotent: int_and(x, y) => x
        if intmask(b_arg_1.tvalue) | intmask(~(b_arg_0.tvalue | b_arg_0.tmask)) == -1:
            self.make_equal_to(op, arg_0)
            self._rule_fired_int_and[3] += 1
            return
        # and_idempotent: int_and(y, x) => x
        if intmask(b_arg_0.tvalue) | intmask(~(b_arg_1.tvalue | b_arg_1.tmask)) == -1:
            self.make_equal_to(op, arg_1)
            self._rule_fired_int_and[3] += 1
            return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            arg_1_int_and = self.optimizer.as_operation(arg_1, rop.INT_AND)
            if arg_1_int_and is not None:
                arg_1_0 = get_box_replacement(arg_1_int_and.getarg(0))
                b_arg_1_0 = self.getintbound(arg_1_0)
                arg_1_1 = get_box_replacement(arg_1_int_and.getarg(1))
                b_arg_1_1 = self.getintbound(arg_1_1)
                if b_arg_1_0.is_constant():
                    C_arg_1_0 = b_arg_1_0.get_constant_int()
                    # and_reassoc_consts: int_and(C2, int_and(C1, x)) => int_and(x, C)
                    C = C_arg_1_0 & C_arg_0
                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_1_1, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_and[1] += 1
                    return
                if b_arg_1_1.is_constant():
                    C_arg_1_1 = b_arg_1_1.get_constant_int()
                    # and_reassoc_consts: int_and(C2, int_and(x, C1)) => int_and(x, C)
                    C = C_arg_1_1 & C_arg_0
                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_1_0, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_and[1] += 1
                    return
        else:
            arg_0_int_and = self.optimizer.as_operation(arg_0, rop.INT_AND)
            if arg_0_int_and is not None:
                arg_0_0 = get_box_replacement(arg_0_int_and.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_and.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                if b_arg_0_0.is_constant():
                    C_arg_0_0 = b_arg_0_0.get_constant_int()
                    if b_arg_1.is_constant():
                        C_arg_1 = b_arg_1.get_constant_int()
                        # and_reassoc_consts: int_and(int_and(C1, x), C2) => int_and(x, C)
                        C = C_arg_0_0 & C_arg_1
                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1, ConstInt(C)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_and[1] += 1
                        return
                if b_arg_0_1.is_constant():
                    C_arg_0_1 = b_arg_0_1.get_constant_int()
                    if b_arg_1.is_constant():
                        C_arg_1 = b_arg_1.get_constant_int()
                        # and_reassoc_consts: int_and(int_and(x, C1), C2) => int_and(x, C)
                        C = C_arg_0_1 & C_arg_1
                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(C)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_and[1] += 1
                        return
                # and_absorb: int_and(int_and(a, b), a) => int_and(a, b)
                if self._eq(arg_1, b_arg_1, arg_0_0, b_arg_0_0):
                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, arg_0_1])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_and[6] += 1
                    return
                # and_absorb: int_and(int_and(b, a), a) => int_and(a, b)
                if self._eq(arg_1, b_arg_1, arg_0_1, b_arg_0_1):
                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1, arg_0_0])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_and[6] += 1
                    return
            else:
                arg_0_int_or = self.optimizer.as_operation(arg_0, rop.INT_OR)
                if arg_0_int_or is not None:
                    arg_0_0 = get_box_replacement(arg_0_int_or.getarg(0))
                    b_arg_0_0 = self.getintbound(arg_0_0)
                    arg_0_1 = get_box_replacement(arg_0_int_or.getarg(1))
                    b_arg_0_1 = self.getintbound(arg_0_1)
                    # and_or: int_and(int_or(x, y), z) => int_and(x, z)
                    if b_arg_0_1.and_bound(b_arg_1).known_eq_const(0):
                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, arg_1])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_and[4] += 1
                        return
                    # and_or: int_and(int_or(y, x), z) => int_and(x, z)
                    if b_arg_0_0.and_bound(b_arg_1).known_eq_const(0):
                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1, arg_1])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_and[4] += 1
                        return
        arg_1_int_and = self.optimizer.as_operation(arg_1, rop.INT_AND)
        if arg_1_int_and is not None:
            arg_1_0 = get_box_replacement(arg_1_int_and.getarg(0))
            b_arg_1_0 = self.getintbound(arg_1_0)
            arg_1_1 = get_box_replacement(arg_1_int_and.getarg(1))
            b_arg_1_1 = self.getintbound(arg_1_1)
            # and_absorb: int_and(a, int_and(a, b)) => int_and(a, b)
            if self._eq(arg_1_0, b_arg_1_0, arg_0, b_arg_0):
                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0, arg_1_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_and[6] += 1
                return
            # and_absorb: int_and(a, int_and(b, a)) => int_and(a, b)
            if self._eq(arg_1_1, b_arg_1_1, arg_0, b_arg_0):
                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0, arg_1_0])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_and[6] += 1
                return
        else:
            arg_1_int_or = self.optimizer.as_operation(arg_1, rop.INT_OR)
            if arg_1_int_or is not None:
                arg_1_0 = get_box_replacement(arg_1_int_or.getarg(0))
                b_arg_1_0 = self.getintbound(arg_1_0)
                arg_1_1 = get_box_replacement(arg_1_int_or.getarg(1))
                b_arg_1_1 = self.getintbound(arg_1_1)
                # and_or: int_and(z, int_or(x, y)) => int_and(x, z)
                if b_arg_1_1.and_bound(b_arg_0).known_eq_const(0):
                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_1_0, arg_0])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_and[4] += 1
                    return
                # and_or: int_and(z, int_or(y, x)) => int_and(x, z)
                if b_arg_1_0.and_bound(b_arg_0).known_eq_const(0):
                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_1_1, arg_0])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_and[4] += 1
                    return
        return self.emit(op)
    _rule_names_int_or = ['or_x_x', 'or_known_result', 'or_absorb', 'or_idempotent', 'or_and_two_parts', 'or_reassoc_consts']
    _rule_fired_int_or = [0] * 6
    _all_rules_fired.append(('int_or', _rule_names_int_or, _rule_fired_int_or))
    def optimize_INT_OR(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        # or_known_result: int_or(a, b) => C
        bound = b_arg_0.or_bound(b_arg_1)
        if bound.is_constant():
            C = bound.get_constant_int()
            self.make_equal_to(op, ConstInt(C))
            self._rule_fired_int_or[1] += 1
            return
        # or_known_result: int_or(b, a) => C
        bound = b_arg_1.or_bound(b_arg_0)
        if bound.is_constant():
            C = bound.get_constant_int()
            self.make_equal_to(op, ConstInt(C))
            self._rule_fired_int_or[1] += 1
            return
        # or_x_x: int_or(a, a) => a
        if self._eq(arg_1, b_arg_1, arg_0, b_arg_0):
            self.make_equal_to(op, arg_0)
            self._rule_fired_int_or[0] += 1
            return
        # or_idempotent: int_or(x, y) => x
        if intmask(b_arg_0.tvalue) | intmask(~(b_arg_1.tvalue | b_arg_1.tmask)) == -1:
            self.make_equal_to(op, arg_0)
            self._rule_fired_int_or[3] += 1
            return
        # or_idempotent: int_or(y, x) => x
        if intmask(b_arg_1.tvalue) | intmask(~(b_arg_0.tvalue | b_arg_0.tmask)) == -1:
            self.make_equal_to(op, arg_1)
            self._rule_fired_int_or[3] += 1
            return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            arg_1_int_or = self.optimizer.as_operation(arg_1, rop.INT_OR)
            if arg_1_int_or is not None:
                arg_1_0 = get_box_replacement(arg_1_int_or.getarg(0))
                b_arg_1_0 = self.getintbound(arg_1_0)
                arg_1_1 = get_box_replacement(arg_1_int_or.getarg(1))
                b_arg_1_1 = self.getintbound(arg_1_1)
                if b_arg_1_0.is_constant():
                    C_arg_1_0 = b_arg_1_0.get_constant_int()
                    # or_reassoc_consts: int_or(C2, int_or(C1, x)) => int_or(x, C)
                    C = C_arg_1_0 | C_arg_0
                    newop = self.replace_op_with(op, rop.INT_OR, args=[arg_1_1, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_or[5] += 1
                    return
                if b_arg_1_1.is_constant():
                    C_arg_1_1 = b_arg_1_1.get_constant_int()
                    # or_reassoc_consts: int_or(C2, int_or(x, C1)) => int_or(x, C)
                    C = C_arg_1_1 | C_arg_0
                    newop = self.replace_op_with(op, rop.INT_OR, args=[arg_1_0, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_or[5] += 1
                    return
        else:
            arg_0_int_and = self.optimizer.as_operation(arg_0, rop.INT_AND)
            if arg_0_int_and is not None:
                arg_0_0 = get_box_replacement(arg_0_int_and.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_and.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                if b_arg_0_0.is_constant():
                    C_arg_0_0 = b_arg_0_0.get_constant_int()
                    arg_1_int_and = self.optimizer.as_operation(arg_1, rop.INT_AND)
                    if arg_1_int_and is not None:
                        arg_1_0 = get_box_replacement(arg_1_int_and.getarg(0))
                        b_arg_1_0 = self.getintbound(arg_1_0)
                        arg_1_1 = get_box_replacement(arg_1_int_and.getarg(1))
                        b_arg_1_1 = self.getintbound(arg_1_1)
                        if b_arg_1_0.is_constant():
                            C_arg_1_0 = b_arg_1_0.get_constant_int()
                            # or_and_two_parts: int_or(int_and(C1, x), int_and(C2, x)) => int_and(x, C)
                            if self._eq(arg_1_1, b_arg_1_1, arg_0_1, b_arg_0_1):
                                C = C_arg_0_0 | C_arg_1_0
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
                            # or_and_two_parts: int_or(int_and(C2, x), int_and(C1, x)) => int_and(x, C)
                            if self._eq(arg_1_1, b_arg_1_1, arg_0_1, b_arg_0_1):
                                C = C_arg_1_0 | C_arg_0_0
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
                        if b_arg_1_1.is_constant():
                            C_arg_1_1 = b_arg_1_1.get_constant_int()
                            # or_and_two_parts: int_or(int_and(C2, x), int_and(x, C1)) => int_and(x, C)
                            if self._eq(arg_1_0, b_arg_1_0, arg_0_1, b_arg_0_1):
                                C = C_arg_1_1 | C_arg_0_0
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
                            # or_and_two_parts: int_or(int_and(C1, x), int_and(x, C2)) => int_and(x, C)
                            if self._eq(arg_1_0, b_arg_1_0, arg_0_1, b_arg_0_1):
                                C = C_arg_0_0 | C_arg_1_1
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
                if b_arg_0_1.is_constant():
                    C_arg_0_1 = b_arg_0_1.get_constant_int()
                    arg_1_int_and = self.optimizer.as_operation(arg_1, rop.INT_AND)
                    if arg_1_int_and is not None:
                        arg_1_0 = get_box_replacement(arg_1_int_and.getarg(0))
                        b_arg_1_0 = self.getintbound(arg_1_0)
                        arg_1_1 = get_box_replacement(arg_1_int_and.getarg(1))
                        b_arg_1_1 = self.getintbound(arg_1_1)
                        if b_arg_1_0.is_constant():
                            C_arg_1_0 = b_arg_1_0.get_constant_int()
                            # or_and_two_parts: int_or(int_and(x, C1), int_and(C2, x)) => int_and(x, C)
                            if self._eq(arg_1_1, b_arg_1_1, arg_0_0, b_arg_0_0):
                                C = C_arg_0_1 | C_arg_1_0
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
                            # or_and_two_parts: int_or(int_and(x, C2), int_and(C1, x)) => int_and(x, C)
                            if self._eq(arg_1_1, b_arg_1_1, arg_0_0, b_arg_0_0):
                                C = C_arg_1_0 | C_arg_0_1
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
                        if b_arg_1_1.is_constant():
                            C_arg_1_1 = b_arg_1_1.get_constant_int()
                            # or_and_two_parts: int_or(int_and(x, C1), int_and(x, C2)) => int_and(x, C)
                            if self._eq(arg_1_0, b_arg_1_0, arg_0_0, b_arg_0_0):
                                C = C_arg_0_1 | C_arg_1_1
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
                            # or_and_two_parts: int_or(int_and(x, C2), int_and(x, C1)) => int_and(x, C)
                            if self._eq(arg_1_0, b_arg_1_0, arg_0_0, b_arg_0_0):
                                C = C_arg_1_1 | C_arg_0_1
                                newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_or[4] += 1
                                return
            else:
                arg_0_int_or = self.optimizer.as_operation(arg_0, rop.INT_OR)
                if arg_0_int_or is not None:
                    arg_0_0 = get_box_replacement(arg_0_int_or.getarg(0))
                    b_arg_0_0 = self.getintbound(arg_0_0)
                    arg_0_1 = get_box_replacement(arg_0_int_or.getarg(1))
                    b_arg_0_1 = self.getintbound(arg_0_1)
                    if b_arg_0_0.is_constant():
                        C_arg_0_0 = b_arg_0_0.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # or_reassoc_consts: int_or(int_or(C1, x), C2) => int_or(x, C)
                            C = C_arg_0_0 | C_arg_1
                            newop = self.replace_op_with(op, rop.INT_OR, args=[arg_0_1, ConstInt(C)])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_or[5] += 1
                            return
                    if b_arg_0_1.is_constant():
                        C_arg_0_1 = b_arg_0_1.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # or_reassoc_consts: int_or(int_or(x, C1), C2) => int_or(x, C)
                            C = C_arg_0_1 | C_arg_1
                            newop = self.replace_op_with(op, rop.INT_OR, args=[arg_0_0, ConstInt(C)])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_or[5] += 1
                            return
                    # or_absorb: int_or(int_or(a, b), a) => int_or(a, b)
                    if self._eq(arg_1, b_arg_1, arg_0_0, b_arg_0_0):
                        newop = self.replace_op_with(op, rop.INT_OR, args=[arg_0_0, arg_0_1])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_or[2] += 1
                        return
                    # or_absorb: int_or(int_or(b, a), a) => int_or(a, b)
                    if self._eq(arg_1, b_arg_1, arg_0_1, b_arg_0_1):
                        newop = self.replace_op_with(op, rop.INT_OR, args=[arg_0_1, arg_0_0])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_or[2] += 1
                        return
        arg_1_int_or = self.optimizer.as_operation(arg_1, rop.INT_OR)
        if arg_1_int_or is not None:
            arg_1_0 = get_box_replacement(arg_1_int_or.getarg(0))
            b_arg_1_0 = self.getintbound(arg_1_0)
            arg_1_1 = get_box_replacement(arg_1_int_or.getarg(1))
            b_arg_1_1 = self.getintbound(arg_1_1)
            # or_absorb: int_or(a, int_or(a, b)) => int_or(a, b)
            if self._eq(arg_1_0, b_arg_1_0, arg_0, b_arg_0):
                newop = self.replace_op_with(op, rop.INT_OR, args=[arg_0, arg_1_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_or[2] += 1
                return
            # or_absorb: int_or(a, int_or(b, a)) => int_or(a, b)
            if self._eq(arg_1_1, b_arg_1_1, arg_0, b_arg_0):
                newop = self.replace_op_with(op, rop.INT_OR, args=[arg_0, arg_1_0])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_or[2] += 1
                return
        return self.emit(op)
    _rule_names_int_xor = ['xor_x_x', 'xor_reassoc_consts', 'xor_absorb', 'xor_zero', 'xor_minus_1', 'xor_known_result', 'xor_is_not']
    _rule_fired_int_xor = [0] * 7
    _all_rules_fired.append(('int_xor', _rule_names_int_xor, _rule_fired_int_xor))
    def optimize_INT_XOR(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            if b_arg_1.is_constant():
                C_arg_1 = b_arg_1.get_constant_int()
                # xor_known_result: int_xor(C1, C2) => C
                C = C_arg_0 ^ C_arg_1
                self.make_equal_to(op, ConstInt(C))
                self._rule_fired_int_xor[5] += 1
                return
                # xor_known_result: int_xor(C2, C1) => C
                C = C_arg_1 ^ C_arg_0
                self.make_equal_to(op, ConstInt(C))
                self._rule_fired_int_xor[5] += 1
                return
        # xor_x_x: int_xor(a, a) => 0
        if self._eq(arg_1, b_arg_1, arg_0, b_arg_0):
            self.make_constant_int(op, 0)
            self._rule_fired_int_xor[0] += 1
            return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # xor_zero: int_xor(0, a) => a
            if C_arg_0 == 0:
                self.make_equal_to(op, arg_1)
                self._rule_fired_int_xor[3] += 1
                return
        else:
            arg_0_int_xor = self.optimizer.as_operation(arg_0, rop.INT_XOR)
            if arg_0_int_xor is not None:
                arg_0_0 = get_box_replacement(arg_0_int_xor.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_xor.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                # xor_absorb: int_xor(int_xor(a, b), b) => a
                if self._eq(arg_1, b_arg_1, arg_0_1, b_arg_0_1):
                    self.make_equal_to(op, arg_0_0)
                    self._rule_fired_int_xor[2] += 1
                    return
                # xor_absorb: int_xor(int_xor(b, a), b) => a
                if self._eq(arg_1, b_arg_1, arg_0_0, b_arg_0_0):
                    self.make_equal_to(op, arg_0_1)
                    self._rule_fired_int_xor[2] += 1
                    return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # xor_zero: int_xor(a, 0) => a
            if C_arg_1 == 0:
                self.make_equal_to(op, arg_0)
                self._rule_fired_int_xor[3] += 1
                return
        else:
            arg_1_int_xor = self.optimizer.as_operation(arg_1, rop.INT_XOR)
            if arg_1_int_xor is not None:
                arg_1_0 = get_box_replacement(arg_1_int_xor.getarg(0))
                b_arg_1_0 = self.getintbound(arg_1_0)
                arg_1_1 = get_box_replacement(arg_1_int_xor.getarg(1))
                b_arg_1_1 = self.getintbound(arg_1_1)
                # xor_absorb: int_xor(b, int_xor(a, b)) => a
                if self._eq(arg_1_1, b_arg_1_1, arg_0, b_arg_0):
                    self.make_equal_to(op, arg_1_0)
                    self._rule_fired_int_xor[2] += 1
                    return
                # xor_absorb: int_xor(b, int_xor(b, a)) => a
                if self._eq(arg_1_0, b_arg_1_0, arg_0, b_arg_0):
                    self.make_equal_to(op, arg_1_1)
                    self._rule_fired_int_xor[2] += 1
                    return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            arg_1_int_xor = self.optimizer.as_operation(arg_1, rop.INT_XOR)
            if arg_1_int_xor is not None:
                arg_1_0 = get_box_replacement(arg_1_int_xor.getarg(0))
                b_arg_1_0 = self.getintbound(arg_1_0)
                arg_1_1 = get_box_replacement(arg_1_int_xor.getarg(1))
                b_arg_1_1 = self.getintbound(arg_1_1)
                if b_arg_1_0.is_constant():
                    C_arg_1_0 = b_arg_1_0.get_constant_int()
                    # xor_reassoc_consts: int_xor(C2, int_xor(C1, x)) => int_xor(x, C)
                    C = C_arg_1_0 ^ C_arg_0
                    newop = self.replace_op_with(op, rop.INT_XOR, args=[arg_1_1, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_xor[1] += 1
                    return
                if b_arg_1_1.is_constant():
                    C_arg_1_1 = b_arg_1_1.get_constant_int()
                    # xor_reassoc_consts: int_xor(C2, int_xor(x, C1)) => int_xor(x, C)
                    C = C_arg_1_1 ^ C_arg_0
                    newop = self.replace_op_with(op, rop.INT_XOR, args=[arg_1_0, ConstInt(C)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_xor[1] += 1
                    return
            # xor_minus_1: int_xor(-1, x) => int_invert(x)
            if C_arg_0 == -1:
                newop = self.replace_op_with(op, rop.INT_INVERT, args=[arg_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_xor[4] += 1
                return
            # xor_is_not: int_xor(1, x) => int_is_zero(x)
            if C_arg_0 == 1:
                if b_arg_1.is_bool():
                    newop = self.replace_op_with(op, rop.INT_IS_ZERO, args=[arg_1])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_xor[6] += 1
                    return
        else:
            arg_0_int_xor = self.optimizer.as_operation(arg_0, rop.INT_XOR)
            if arg_0_int_xor is not None:
                arg_0_0 = get_box_replacement(arg_0_int_xor.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_xor.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                if b_arg_0_0.is_constant():
                    C_arg_0_0 = b_arg_0_0.get_constant_int()
                    if b_arg_1.is_constant():
                        C_arg_1 = b_arg_1.get_constant_int()
                        # xor_reassoc_consts: int_xor(int_xor(C1, x), C2) => int_xor(x, C)
                        C = C_arg_0_0 ^ C_arg_1
                        newop = self.replace_op_with(op, rop.INT_XOR, args=[arg_0_1, ConstInt(C)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_xor[1] += 1
                        return
                if b_arg_0_1.is_constant():
                    C_arg_0_1 = b_arg_0_1.get_constant_int()
                    if b_arg_1.is_constant():
                        C_arg_1 = b_arg_1.get_constant_int()
                        # xor_reassoc_consts: int_xor(int_xor(x, C1), C2) => int_xor(x, C)
                        C = C_arg_0_1 ^ C_arg_1
                        newop = self.replace_op_with(op, rop.INT_XOR, args=[arg_0_0, ConstInt(C)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_int_xor[1] += 1
                        return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # xor_minus_1: int_xor(x, -1) => int_invert(x)
            if C_arg_1 == -1:
                newop = self.replace_op_with(op, rop.INT_INVERT, args=[arg_0])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_xor[4] += 1
                return
            # xor_is_not: int_xor(x, 1) => int_is_zero(x)
            if C_arg_1 == 1:
                if b_arg_0.is_bool():
                    newop = self.replace_op_with(op, rop.INT_IS_ZERO, args=[arg_0])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_xor[6] += 1
                    return
        return self.emit(op)
    _rule_names_int_lshift = ['lshift_zero_x', 'lshift_x_zero', 'lshift_rshift_c_c', 'lshift_and_rshift', 'lshift_urshift_c_c', 'lshift_and_urshift', 'lshift_lshift_c_c']
    _rule_fired_int_lshift = [0] * 7
    _all_rules_fired.append(('int_lshift', _rule_names_int_lshift, _rule_fired_int_lshift))
    def optimize_INT_LSHIFT(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # lshift_zero_x: int_lshift(0, x) => 0
            if C_arg_0 == 0:
                self.make_constant_int(op, 0)
                self._rule_fired_int_lshift[0] += 1
                return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # lshift_x_zero: int_lshift(x, 0) => x
            if C_arg_1 == 0:
                self.make_equal_to(op, arg_0)
                self._rule_fired_int_lshift[1] += 1
                return
        arg_0_int_and = self.optimizer.as_operation(arg_0, rop.INT_AND)
        if arg_0_int_and is not None:
            arg_0_0 = get_box_replacement(arg_0_int_and.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            arg_0_1 = get_box_replacement(arg_0_int_and.getarg(1))
            b_arg_0_1 = self.getintbound(arg_0_1)
            if b_arg_0_0.is_constant():
                C_arg_0_0 = b_arg_0_0.get_constant_int()
                arg_0_1_int_rshift = self.optimizer.as_operation(arg_0_1, rop.INT_RSHIFT)
                if arg_0_1_int_rshift is not None:
                    arg_0_1_0 = get_box_replacement(arg_0_1_int_rshift.getarg(0))
                    b_arg_0_1_0 = self.getintbound(arg_0_1_0)
                    arg_0_1_1 = get_box_replacement(arg_0_1_int_rshift.getarg(1))
                    b_arg_0_1_1 = self.getintbound(arg_0_1_1)
                    if b_arg_0_1_1.is_constant():
                        C_arg_0_1_1 = b_arg_0_1_1.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # lshift_and_rshift: int_lshift(int_and(C2, int_rshift(x, C1)), C1) => int_and(x, C)
                            if C_arg_1 == C_arg_0_1_1:
                                if 0 <= C_arg_0_1_1 and C_arg_0_1_1 < LONG_BIT:
                                    C = C_arg_0_0 << C_arg_0_1_1
                                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1_0, ConstInt(C)])
                                    self.optimizer.send_extra_operation(newop)
                                    self._rule_fired_int_lshift[3] += 1
                                    return
                else:
                    arg_0_1_uint_rshift = self.optimizer.as_operation(arg_0_1, rop.UINT_RSHIFT)
                    if arg_0_1_uint_rshift is not None:
                        arg_0_1_0 = get_box_replacement(arg_0_1_uint_rshift.getarg(0))
                        b_arg_0_1_0 = self.getintbound(arg_0_1_0)
                        arg_0_1_1 = get_box_replacement(arg_0_1_uint_rshift.getarg(1))
                        b_arg_0_1_1 = self.getintbound(arg_0_1_1)
                        if b_arg_0_1_1.is_constant():
                            C_arg_0_1_1 = b_arg_0_1_1.get_constant_int()
                            if b_arg_1.is_constant():
                                C_arg_1 = b_arg_1.get_constant_int()
                                # lshift_and_urshift: int_lshift(int_and(C2, uint_rshift(x, C1)), C1) => int_and(x, C)
                                if C_arg_1 == C_arg_0_1_1:
                                    if 0 <= C_arg_0_1_1 and C_arg_0_1_1 < LONG_BIT:
                                        C = C_arg_0_0 << C_arg_0_1_1
                                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_1_0, ConstInt(C)])
                                        self.optimizer.send_extra_operation(newop)
                                        self._rule_fired_int_lshift[5] += 1
                                        return
            else:
                arg_0_0_int_rshift = self.optimizer.as_operation(arg_0_0, rop.INT_RSHIFT)
                if arg_0_0_int_rshift is not None:
                    arg_0_0_0 = get_box_replacement(arg_0_0_int_rshift.getarg(0))
                    b_arg_0_0_0 = self.getintbound(arg_0_0_0)
                    arg_0_0_1 = get_box_replacement(arg_0_0_int_rshift.getarg(1))
                    b_arg_0_0_1 = self.getintbound(arg_0_0_1)
                    if b_arg_0_0_1.is_constant():
                        C_arg_0_0_1 = b_arg_0_0_1.get_constant_int()
                        if b_arg_0_1.is_constant():
                            C_arg_0_1 = b_arg_0_1.get_constant_int()
                            if b_arg_1.is_constant():
                                C_arg_1 = b_arg_1.get_constant_int()
                                # lshift_and_rshift: int_lshift(int_and(int_rshift(x, C1), C2), C1) => int_and(x, C)
                                if C_arg_1 == C_arg_0_0_1:
                                    if 0 <= C_arg_0_0_1 and C_arg_0_0_1 < LONG_BIT:
                                        C = C_arg_0_1 << C_arg_0_0_1
                                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0_0, ConstInt(C)])
                                        self.optimizer.send_extra_operation(newop)
                                        self._rule_fired_int_lshift[3] += 1
                                        return
                else:
                    arg_0_0_uint_rshift = self.optimizer.as_operation(arg_0_0, rop.UINT_RSHIFT)
                    if arg_0_0_uint_rshift is not None:
                        arg_0_0_0 = get_box_replacement(arg_0_0_uint_rshift.getarg(0))
                        b_arg_0_0_0 = self.getintbound(arg_0_0_0)
                        arg_0_0_1 = get_box_replacement(arg_0_0_uint_rshift.getarg(1))
                        b_arg_0_0_1 = self.getintbound(arg_0_0_1)
                        if b_arg_0_0_1.is_constant():
                            C_arg_0_0_1 = b_arg_0_0_1.get_constant_int()
                            if b_arg_0_1.is_constant():
                                C_arg_0_1 = b_arg_0_1.get_constant_int()
                                if b_arg_1.is_constant():
                                    C_arg_1 = b_arg_1.get_constant_int()
                                    # lshift_and_urshift: int_lshift(int_and(uint_rshift(x, C1), C2), C1) => int_and(x, C)
                                    if C_arg_1 == C_arg_0_0_1:
                                        if 0 <= C_arg_0_0_1 and C_arg_0_0_1 < LONG_BIT:
                                            C = C_arg_0_1 << C_arg_0_0_1
                                            newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0_0, ConstInt(C)])
                                            self.optimizer.send_extra_operation(newop)
                                            self._rule_fired_int_lshift[5] += 1
                                            return
        else:
            arg_0_int_lshift = self.optimizer.as_operation(arg_0, rop.INT_LSHIFT)
            if arg_0_int_lshift is not None:
                arg_0_0 = get_box_replacement(arg_0_int_lshift.getarg(0))
                b_arg_0_0 = self.getintbound(arg_0_0)
                arg_0_1 = get_box_replacement(arg_0_int_lshift.getarg(1))
                b_arg_0_1 = self.getintbound(arg_0_1)
                if b_arg_0_1.is_constant():
                    C_arg_0_1 = b_arg_0_1.get_constant_int()
                    if b_arg_1.is_constant():
                        C_arg_1 = b_arg_1.get_constant_int()
                        # lshift_lshift_c_c: int_lshift(int_lshift(x, C1), C2) => int_lshift(x, C)
                        if 0 <= C_arg_0_1 and C_arg_0_1 < LONG_BIT and 0 <= C_arg_1 and C_arg_1 < LONG_BIT:
                            C = intmask(r_uint(C_arg_0_1) + r_uint(C_arg_1))
                            if C < LONG_BIT:
                                newop = self.replace_op_with(op, rop.INT_LSHIFT, args=[arg_0_0, ConstInt(C)])
                                self.optimizer.send_extra_operation(newop)
                                self._rule_fired_int_lshift[6] += 1
                                return
            else:
                arg_0_int_rshift = self.optimizer.as_operation(arg_0, rop.INT_RSHIFT)
                if arg_0_int_rshift is not None:
                    arg_0_0 = get_box_replacement(arg_0_int_rshift.getarg(0))
                    b_arg_0_0 = self.getintbound(arg_0_0)
                    arg_0_1 = get_box_replacement(arg_0_int_rshift.getarg(1))
                    b_arg_0_1 = self.getintbound(arg_0_1)
                    if b_arg_0_1.is_constant():
                        C_arg_0_1 = b_arg_0_1.get_constant_int()
                        if b_arg_1.is_constant():
                            C_arg_1 = b_arg_1.get_constant_int()
                            # lshift_rshift_c_c: int_lshift(int_rshift(x, C1), C1) => int_and(x, C)
                            if C_arg_1 == C_arg_0_1:
                                if 0 <= C_arg_0_1 and C_arg_0_1 < LONG_BIT:
                                    C = -1 << C_arg_0_1
                                    newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(C)])
                                    self.optimizer.send_extra_operation(newop)
                                    self._rule_fired_int_lshift[2] += 1
                                    return
                else:
                    arg_0_uint_rshift = self.optimizer.as_operation(arg_0, rop.UINT_RSHIFT)
                    if arg_0_uint_rshift is not None:
                        arg_0_0 = get_box_replacement(arg_0_uint_rshift.getarg(0))
                        b_arg_0_0 = self.getintbound(arg_0_0)
                        arg_0_1 = get_box_replacement(arg_0_uint_rshift.getarg(1))
                        b_arg_0_1 = self.getintbound(arg_0_1)
                        if b_arg_0_1.is_constant():
                            C_arg_0_1 = b_arg_0_1.get_constant_int()
                            if b_arg_1.is_constant():
                                C_arg_1 = b_arg_1.get_constant_int()
                                # lshift_urshift_c_c: int_lshift(uint_rshift(x, C1), C1) => int_and(x, C)
                                if C_arg_1 == C_arg_0_1:
                                    if 0 <= C_arg_0_1 and C_arg_0_1 < LONG_BIT:
                                        C = -1 << C_arg_0_1
                                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(C)])
                                        self.optimizer.send_extra_operation(newop)
                                        self._rule_fired_int_lshift[4] += 1
                                        return
        return self.emit(op)
    _rule_names_int_rshift = ['rshift_zero_x', 'rshift_x_zero', 'rshift_known_result', 'rshift_lshift', 'rshift_rshift_c_c']
    _rule_fired_int_rshift = [0] * 5
    _all_rules_fired.append(('int_rshift', _rule_names_int_rshift, _rule_fired_int_rshift))
    def optimize_INT_RSHIFT(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # rshift_zero_x: int_rshift(0, x) => 0
            if C_arg_0 == 0:
                self.make_constant_int(op, 0)
                self._rule_fired_int_rshift[0] += 1
                return
        # rshift_known_result: int_rshift(a, b) => C
        bound = b_arg_0.rshift_bound(b_arg_1)
        if bound.is_constant():
            C = bound.get_constant_int()
            self.make_equal_to(op, ConstInt(C))
            self._rule_fired_int_rshift[2] += 1
            return
        arg_0_int_lshift = self.optimizer.as_operation(arg_0, rop.INT_LSHIFT)
        if arg_0_int_lshift is not None:
            arg_0_0 = get_box_replacement(arg_0_int_lshift.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            arg_0_1 = get_box_replacement(arg_0_int_lshift.getarg(1))
            b_arg_0_1 = self.getintbound(arg_0_1)
            # rshift_lshift: int_rshift(int_lshift(x, y), y) => x
            if self._eq(arg_1, b_arg_1, arg_0_1, b_arg_0_1):
                if b_arg_0_0.lshift_bound_cannot_overflow(b_arg_0_1):
                    self.make_equal_to(op, arg_0_0)
                    self._rule_fired_int_rshift[3] += 1
                    return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # rshift_x_zero: int_rshift(x, 0) => x
            if C_arg_1 == 0:
                self.make_equal_to(op, arg_0)
                self._rule_fired_int_rshift[1] += 1
                return
        arg_0_int_rshift = self.optimizer.as_operation(arg_0, rop.INT_RSHIFT)
        if arg_0_int_rshift is not None:
            arg_0_0 = get_box_replacement(arg_0_int_rshift.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            arg_0_1 = get_box_replacement(arg_0_int_rshift.getarg(1))
            b_arg_0_1 = self.getintbound(arg_0_1)
            if b_arg_0_1.is_constant():
                C_arg_0_1 = b_arg_0_1.get_constant_int()
                if b_arg_1.is_constant():
                    C_arg_1 = b_arg_1.get_constant_int()
                    # rshift_rshift_c_c: int_rshift(int_rshift(x, C1), C2) => int_rshift(x, C)
                    if 0 <= C_arg_0_1 and C_arg_0_1 < LONG_BIT and 0 <= C_arg_1 and C_arg_1 < LONG_BIT:
                        C = min(intmask(r_uint(C_arg_0_1) + r_uint(C_arg_1)), intmask(r_uint(LONG_BIT) - r_uint(1)))
                        if 0 <= C and C < LONG_BIT:
                            newop = self.replace_op_with(op, rop.INT_RSHIFT, args=[arg_0_0, ConstInt(C)])
                            self.optimizer.send_extra_operation(newop)
                            self._rule_fired_int_rshift[4] += 1
                            return
        return self.emit(op)
    _rule_names_uint_rshift = ['urshift_zero_x', 'urshift_x_zero', 'urshift_known_result', 'urshift_lshift_x_c_c']
    _rule_fired_uint_rshift = [0] * 4
    _all_rules_fired.append(('uint_rshift', _rule_names_uint_rshift, _rule_fired_uint_rshift))
    def optimize_UINT_RSHIFT(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # urshift_zero_x: uint_rshift(0, x) => 0
            if C_arg_0 == 0:
                self.make_constant_int(op, 0)
                self._rule_fired_uint_rshift[0] += 1
                return
        # urshift_known_result: uint_rshift(a, b) => C
        bound = b_arg_0.urshift_bound(b_arg_1)
        if bound.is_constant():
            C = bound.get_constant_int()
            self.make_equal_to(op, ConstInt(C))
            self._rule_fired_uint_rshift[2] += 1
            return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # urshift_x_zero: uint_rshift(x, 0) => x
            if C_arg_1 == 0:
                self.make_equal_to(op, arg_0)
                self._rule_fired_uint_rshift[1] += 1
                return
        arg_0_int_lshift = self.optimizer.as_operation(arg_0, rop.INT_LSHIFT)
        if arg_0_int_lshift is not None:
            arg_0_0 = get_box_replacement(arg_0_int_lshift.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            arg_0_1 = get_box_replacement(arg_0_int_lshift.getarg(1))
            b_arg_0_1 = self.getintbound(arg_0_1)
            if b_arg_0_1.is_constant():
                C_arg_0_1 = b_arg_0_1.get_constant_int()
                if b_arg_1.is_constant():
                    C_arg_1 = b_arg_1.get_constant_int()
                    # urshift_lshift_x_c_c: uint_rshift(int_lshift(x, C), C) => int_and(x, mask)
                    if C_arg_1 == C_arg_0_1:
                        mask = intmask(r_uint(-1 << C_arg_0_1) >> r_uint(C_arg_0_1))
                        newop = self.replace_op_with(op, rop.INT_AND, args=[arg_0_0, ConstInt(mask)])
                        self.optimizer.send_extra_operation(newop)
                        self._rule_fired_uint_rshift[3] += 1
                        return
        return self.emit(op)
    _rule_names_int_eq = ['eq_different_knownbits', 'eq_same', 'eq_one', 'eq_zero', 'eq_sub_eq']
    _rule_fired_int_eq = [0] * 5
    _all_rules_fired.append(('int_eq', _rule_names_int_eq, _rule_fired_int_eq))
    def optimize_INT_EQ(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        arg_0_int_sub = self.optimizer.as_operation(arg_0, rop.INT_SUB)
        if arg_0_int_sub is not None:
            arg_0_0 = get_box_replacement(arg_0_int_sub.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            arg_0_1 = get_box_replacement(arg_0_int_sub.getarg(1))
            b_arg_0_1 = self.getintbound(arg_0_1)
            arg_0_1_int_eq = self.optimizer.as_operation(arg_0_1, rop.INT_EQ)
            if arg_0_1_int_eq is not None:
                arg_0_1_0 = get_box_replacement(arg_0_1_int_eq.getarg(0))
                b_arg_0_1_0 = self.getintbound(arg_0_1_0)
                arg_0_1_1 = get_box_replacement(arg_0_1_int_eq.getarg(1))
                b_arg_0_1_1 = self.getintbound(arg_0_1_1)
                # eq_sub_eq: int_eq(int_sub(x, int_eq(x, a)), a) => 0
                if self._eq(arg_0_1_0, b_arg_0_1_0, arg_0_0, b_arg_0_0):
                    if self._eq(arg_1, b_arg_1, arg_0_1_1, b_arg_0_1_1):
                        self.make_constant_int(op, 0)
                        self._rule_fired_int_eq[4] += 1
                        return
                # eq_sub_eq: int_eq(int_sub(x, int_eq(a, x)), a) => 0
                if self._eq(arg_0_1_1, b_arg_0_1_1, arg_0_0, b_arg_0_0):
                    if self._eq(arg_1, b_arg_1, arg_0_1_0, b_arg_0_1_0):
                        self.make_constant_int(op, 0)
                        self._rule_fired_int_eq[4] += 1
                        return
        arg_1_int_sub = self.optimizer.as_operation(arg_1, rop.INT_SUB)
        if arg_1_int_sub is not None:
            arg_1_0 = get_box_replacement(arg_1_int_sub.getarg(0))
            b_arg_1_0 = self.getintbound(arg_1_0)
            arg_1_1 = get_box_replacement(arg_1_int_sub.getarg(1))
            b_arg_1_1 = self.getintbound(arg_1_1)
            arg_1_1_int_eq = self.optimizer.as_operation(arg_1_1, rop.INT_EQ)
            if arg_1_1_int_eq is not None:
                arg_1_1_0 = get_box_replacement(arg_1_1_int_eq.getarg(0))
                b_arg_1_1_0 = self.getintbound(arg_1_1_0)
                arg_1_1_1 = get_box_replacement(arg_1_1_int_eq.getarg(1))
                b_arg_1_1_1 = self.getintbound(arg_1_1_1)
                # eq_sub_eq: int_eq(a, int_sub(x, int_eq(x, a))) => 0
                if self._eq(arg_1_1_0, b_arg_1_1_0, arg_1_0, b_arg_1_0):
                    if self._eq(arg_1_1_1, b_arg_1_1_1, arg_0, b_arg_0):
                        self.make_constant_int(op, 0)
                        self._rule_fired_int_eq[4] += 1
                        return
                # eq_sub_eq: int_eq(a, int_sub(x, int_eq(a, x))) => 0
                if self._eq(arg_1_1_0, b_arg_1_1_0, arg_0, b_arg_0):
                    if self._eq(arg_1_1_1, b_arg_1_1_1, arg_1_0, b_arg_1_0):
                        self.make_constant_int(op, 0)
                        self._rule_fired_int_eq[4] += 1
                        return
        # eq_same: int_eq(x, x) => 1
        if self._eq(arg_1, b_arg_1, arg_0, b_arg_0):
            self.make_constant_int(op, 1)
            self._rule_fired_int_eq[1] += 1
            return
        # eq_different_knownbits: int_eq(x, y) => 0
        if b_arg_0.known_ne(b_arg_1):
            self.make_constant_int(op, 0)
            self._rule_fired_int_eq[0] += 1
            return
        # eq_different_knownbits: int_eq(y, x) => 0
        if b_arg_1.known_ne(b_arg_0):
            self.make_constant_int(op, 0)
            self._rule_fired_int_eq[0] += 1
            return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # eq_one: int_eq(1, x) => x
            if C_arg_0 == 1:
                if b_arg_1.is_bool():
                    self.make_equal_to(op, arg_1)
                    self._rule_fired_int_eq[2] += 1
                    return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # eq_one: int_eq(x, 1) => x
            if C_arg_1 == 1:
                if b_arg_0.is_bool():
                    self.make_equal_to(op, arg_0)
                    self._rule_fired_int_eq[2] += 1
                    return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # eq_zero: int_eq(0, x) => int_is_zero(x)
            if C_arg_0 == 0:
                newop = self.replace_op_with(op, rop.INT_IS_ZERO, args=[arg_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_eq[3] += 1
                return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # eq_zero: int_eq(x, 0) => int_is_zero(x)
            if C_arg_1 == 0:
                newop = self.replace_op_with(op, rop.INT_IS_ZERO, args=[arg_0])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_eq[3] += 1
                return
        return self.emit(op)
    _rule_names_int_ne = ['ne_different_knownbits', 'ne_same', 'ne_zero']
    _rule_fired_int_ne = [0] * 3
    _all_rules_fired.append(('int_ne', _rule_names_int_ne, _rule_fired_int_ne))
    def optimize_INT_NE(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_1 = get_box_replacement(op.getarg(1))
        b_arg_1 = self.getintbound(arg_1)
        # ne_same: int_ne(x, x) => 0
        if self._eq(arg_1, b_arg_1, arg_0, b_arg_0):
            self.make_constant_int(op, 0)
            self._rule_fired_int_ne[1] += 1
            return
        # ne_different_knownbits: int_ne(x, y) => 1
        if b_arg_0.known_ne(b_arg_1):
            self.make_constant_int(op, 1)
            self._rule_fired_int_ne[0] += 1
            return
        # ne_different_knownbits: int_ne(y, x) => 1
        if b_arg_1.known_ne(b_arg_0):
            self.make_constant_int(op, 1)
            self._rule_fired_int_ne[0] += 1
            return
        if b_arg_0.is_constant():
            C_arg_0 = b_arg_0.get_constant_int()
            # ne_zero: int_ne(0, x) => int_is_true(x)
            if C_arg_0 == 0:
                newop = self.replace_op_with(op, rop.INT_IS_TRUE, args=[arg_1])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_ne[2] += 1
                return
        if b_arg_1.is_constant():
            C_arg_1 = b_arg_1.get_constant_int()
            # ne_zero: int_ne(x, 0) => int_is_true(x)
            if C_arg_1 == 0:
                newop = self.replace_op_with(op, rop.INT_IS_TRUE, args=[arg_0])
                self.optimizer.send_extra_operation(newop)
                self._rule_fired_int_ne[2] += 1
                return
        return self.emit(op)
    _rule_names_int_is_true = ['is_true_bool', 'is_true_true', 'is_true_and_minint']
    _rule_fired_int_is_true = [0] * 3
    _all_rules_fired.append(('int_is_true', _rule_names_int_is_true, _rule_fired_int_is_true))
    def optimize_INT_IS_TRUE(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        # is_true_true: int_is_true(x) => 1
        if intmask(b_arg_0.lower) > 0 or intmask(b_arg_0.upper) < 0 or intmask(b_arg_0.tvalue) != 0:
            self.make_constant_int(op, 1)
            self._rule_fired_int_is_true[1] += 1
            return
        # is_true_bool: int_is_true(x) => x
        if b_arg_0.is_bool():
            self.make_equal_to(op, arg_0)
            self._rule_fired_int_is_true[0] += 1
            return
        arg_0_int_and = self.optimizer.as_operation(arg_0, rop.INT_AND)
        if arg_0_int_and is not None:
            arg_0_0 = get_box_replacement(arg_0_int_and.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            arg_0_1 = get_box_replacement(arg_0_int_and.getarg(1))
            b_arg_0_1 = self.getintbound(arg_0_1)
            if b_arg_0_0.is_constant():
                C_arg_0_0 = b_arg_0_0.get_constant_int()
                # is_true_and_minint: int_is_true(int_and(MININT, x)) => int_lt(x, 0)
                if C_arg_0_0 == MININT:
                    newop = self.replace_op_with(op, rop.INT_LT, args=[arg_0_1, ConstInt(0)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_is_true[2] += 1
                    return
            if b_arg_0_1.is_constant():
                C_arg_0_1 = b_arg_0_1.get_constant_int()
                # is_true_and_minint: int_is_true(int_and(x, MININT)) => int_lt(x, 0)
                if C_arg_0_1 == MININT:
                    newop = self.replace_op_with(op, rop.INT_LT, args=[arg_0_0, ConstInt(0)])
                    self.optimizer.send_extra_operation(newop)
                    self._rule_fired_int_is_true[2] += 1
                    return
        return self.emit(op)
    _rule_names_int_is_zero = ['is_zero_true']
    _rule_fired_int_is_zero = [0] * 1
    _all_rules_fired.append(('int_is_zero', _rule_names_int_is_zero, _rule_fired_int_is_zero))
    def optimize_INT_IS_ZERO(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        # is_zero_true: int_is_zero(x) => 0
        if intmask(b_arg_0.lower) > 0 or intmask(b_arg_0.upper) < 0 or intmask(b_arg_0.tvalue) != 0:
            self.make_constant_int(op, 0)
            self._rule_fired_int_is_zero[0] += 1
            return
        return self.emit(op)
    _rule_names_int_force_ge_zero = ['force_ge_zero_pos', 'force_ge_zero_neg']
    _rule_fired_int_force_ge_zero = [0] * 2
    _all_rules_fired.append(('int_force_ge_zero', _rule_names_int_force_ge_zero, _rule_fired_int_force_ge_zero))
    def optimize_INT_FORCE_GE_ZERO(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        # force_ge_zero_neg: int_force_ge_zero(x) => 0
        if b_arg_0.known_lt_const(0):
            self.make_constant_int(op, 0)
            self._rule_fired_int_force_ge_zero[1] += 1
            return
        # force_ge_zero_pos: int_force_ge_zero(x) => x
        if b_arg_0.known_nonnegative():
            self.make_equal_to(op, arg_0)
            self._rule_fired_int_force_ge_zero[0] += 1
            return
        return self.emit(op)
    _rule_names_int_invert = ['invert_invert']
    _rule_fired_int_invert = [0] * 1
    _all_rules_fired.append(('int_invert', _rule_names_int_invert, _rule_fired_int_invert))
    def optimize_INT_INVERT(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_0_int_invert = self.optimizer.as_operation(arg_0, rop.INT_INVERT)
        if arg_0_int_invert is not None:
            arg_0_0 = get_box_replacement(arg_0_int_invert.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            # invert_invert: int_invert(int_invert(x)) => x
            self.make_equal_to(op, arg_0_0)
            self._rule_fired_int_invert[0] += 1
            return
        return self.emit(op)
    _rule_names_int_neg = ['neg_neg']
    _rule_fired_int_neg = [0] * 1
    _all_rules_fired.append(('int_neg', _rule_names_int_neg, _rule_fired_int_neg))
    def optimize_INT_NEG(self, op):
        arg_0 = get_box_replacement(op.getarg(0))
        b_arg_0 = self.getintbound(arg_0)
        arg_0_int_neg = self.optimizer.as_operation(arg_0, rop.INT_NEG)
        if arg_0_int_neg is not None:
            arg_0_0 = get_box_replacement(arg_0_int_neg.getarg(0))
            b_arg_0_0 = self.getintbound(arg_0_0)
            # neg_neg: int_neg(int_neg(x)) => x
            self.make_equal_to(op, arg_0_0)
            self._rule_fired_int_neg[0] += 1
            return
        return self.emit(op)
