code: def _qnn_conv2d_legalize_arm_cpu(attrs, inputs, types):
      target = tvm.target.Target.current(allow_none=False)
      is_depthwise = relay.op.strategy.is_depthwise_conv2d(
          types[0].shape,
          attrs["data_layout"],
          types[1].shape,
          attrs["kernel_layout"],
          attrs["groups"],
      )
      use_int8_on_arm = (not is_depthwise) and attrs[
          "data_layout"
      ] == "NHWC"
      other_options = use_int8_on_arm or target.features.has_dotprod
      if target.features.has_asimd and not other_options:
          return helper_no_fast_int8_hw_legalization(
              attrs, inputs, types, relay.nn.conv2d
          )
      # ARM prefers the dtypes to be same.
      return helper_change_dtypes_to_be_same(
          attrs, inputs, types, relay.qnn.op.conv2d
      )
  
imports: import numpy
  from scipy import special
  import tvm
  from tvm import relay
  from tvm._ffi.base import TVMError
  from tvm.relay.qnn.op.canonicalizations import create_integer_lookup_op
  from ....target.x86 import target_has_features
  from ....topi.utils import is_target
  from ..None import op
label_desc: Use image node_id 18 for calling a global function with example usage: _qnn_conv2d_legalize_arm_cpu(attrs, inputs, types) and returns: helper_change_dtypes_to_be_same, helper_no_fast_int8_hw_legalization