def test_canonicalize_versatile_inputs(self, all_are_int):
        """
        Input graph:

                                             |-> int op 0 if all_are_int else add -> quantize -> dequantize -> output_0
            input -> quantize -> dequantize -|
                                             |-> int op 1 -> quantize -> dequantize -> output_1

        Output graph:

            if all_are_int:

                                   |-> int op 0 -> dequantize -> output_0
                input -> quantize -|
                                   |-> int op 1 -> dequantize -> output_1

            else:

                                   |-> dequantize -> add -> quantize -> dequantize -> output_0
                input -> quantize -|
                                   |-> int op 1 -> dequantize -> output_1
        """
        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)

            # int op 0 (here reshape) path
            if all_are_int:
                reshape = mb.reshape(x=dequantize_1, shape=output_shape)
                quantize_1_0 = mb.quantize(input=reshape, scale=0.1, output_dtype="int8")
                dequantize_2_0 = mb.dequantize(input=quantize_1_0, scale=0.1)
            # float op (here add) path
            else:
                add = mb.add(x=dequantize_1, y=1.0)
                quantize_1_0 = mb.quantize(input=add, scale=0.1, output_dtype="int8")
                dequantize_2_0 = mb.dequantize(input=quantize_1_0, scale=0.1)

            # int op 1 (here reshape) path
            reshape = mb.reshape(x=dequantize_1, shape=output_shape)
            quantize_1_1 = mb.quantize(input=reshape, scale=0.1, output_dtype="int8")
            dequantize_2_1 = mb.dequantize(input=quantize_1_1, scale=0.1)

            return (
                dequantize_2_0,
                dequantize_2_1,
            )

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

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

        Input graph:

                                             |-> int op 0 if all_are_int else add -> quantize -> dequantize -> output_0
            input -> quantize -> dequantize -|
                                             |-> int op 1 -> quantize -> dequantize -> output_1

        Output graph:

            if all_are_int:

                                   |-> int op 0 -> dequantize -> output_0
                input -> quantize -|
                                   |-> int op 1 -> dequantize -> output_1

            else:

                                   |-> dequantize -> add -> quantize -> dequantize -> output_0
                input -> quantize -|
                                   |-> int op 1 -> dequantize -> output_1
        
coremltools/converters/mil/mil/passes/tests/test_quantization_passes.py