def test_canonicalize_int_op(self, op_type):
        """
        Input graph:

            input -> quantize -> dequantize -> int op -> quantize -> dequantize -> output

        Output graph:

            input -> quantize -> int op -> dequantize -> output
        """
        input_shape = (5, 6)
        output_shape = (5, 2, 3)

        @mb.program(input_specs=[mb.TensorSpec(shape=input_shape)], opset_version=ct.target.iOS17)
        def prog(x):
            quantize_0 = mb.quantize(input=x, scale=0.1, output_dtype="int8")
            dequantize_1 = mb.dequantize(input=quantize_0, scale=0.1)
            if op_type == "reshape":
                reshape = mb.reshape(x=dequantize_1, shape=output_shape)
            quantize_1 = mb.quantize(input=reshape, scale=0.1, output_dtype="int8")
            dequantize_2 = mb.dequantize(input=quantize_1, scale=0.1)
            return dequantize_2

        prev_prog, _, _ = apply_pass_and_basic_check(prog, "common::int_op_canonicalization")
        _, _, block = apply_pass_and_basic_check(prog, "common::dead_code_elimination")
        assert get_op_types_in_program(prev_prog) == [
            "quantize",
            "dequantize", "reshape", "quantize",
            "dequantize",
        ]
        assert get_op_types_in_program(prog) == ["quantize", "reshape", "dequantize"]

        assert_model_is_valid(
            prog,
            {"x": input_shape},
            expected_output_shapes={block.outputs[0].name: output_shape},
            minimum_deployment_target=ct.target.iOS17,
            backend=("mlprogram", "fp32"),
        )

        Input graph:

            input -> quantize -> dequantize -> int op -> quantize -> dequantize -> output

        Output graph:

            input -> quantize -> int op -> dequantize -> output
        
coremltools/converters/mil/mil/passes/tests/test_quantization_passes.py