code: def helper_no_fast_int8_hw_legalization(
      attrs, inputs, types, relay_op
  ):
      """Converts QNN operators into a sequence of Relay operators that are friendly to HW that do
      not have fast Int8 arithmetic. For example, for ARM, LLVM utilizes the assembly instructions
      much more efficiently if the convolution or dense operator input datatypes are int16 instead of
      int8. More details are present at https://github.com/apache/tvm/pull/4277.
  
      Parameters
      ----------
      attrs : tvm.ir.Attrs
          Attributes of current convolution
      inputs : list of tvm.relay.Expr
          The args of the Relay expr to be legalized
      types : list of types
          List of input and output types
  
      Returns
      -------
      result : tvm.relay.Expr
          The legalized expr
      """
  
      # Collect the input exprs.
      data, kernel, input_zero_point, kernel_zero_point, _, _ = inputs
  
      shift_data = relay.subtract(
          relay.cast(data, dtype="int16"),
          relay.cast(input_zero_point, dtype="int16"),
      )
      # If kernel zero point is a scalar we can directly subtract it.
      if len(types[3].shape) == 0:
          shift_kernel = relay.subtract(
              relay.cast(kernel, dtype="int16"),
              relay.cast(kernel_zero_point, dtype="int16"),
          )
      # Otherwise it needs to be broadcast.
      else:
          # Determine output axis of kernel for spatial operations.
          if hasattr(attrs, "kernel_layout"):
              output_axis = tvm.tir.layout(
                  attrs["kernel_layout"]
              ).index_of("O")
          # For dense operations, broadcast to [N, K] layout.
          elif isinstance(attrs, relay.op.op_attrs.DenseAttrs):
              output_axis = 0
          # For matrix multiplication instead expand to [K, N] layout.
          elif isinstance(attrs, relay.op.op_attrs.MatmulAttrs):
              output_axis = 1
          else:
              raise TVMError(
                  "Legalization of %s is not yet supported with per channel parameters"
                  % str(type(attrs))
              )
  
          shift_kernel = relay.nn.bias_add(
              relay.cast(kernel, dtype="int16"),
              -relay.cast(kernel_zero_point, dtype="int16"),
              output_axis,
          )
      new_attrs = {k: attrs[k] for k in attrs.keys()}
      return relay_op(shift_data, shift_kernel, **new_attrs)
  
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 11 for calling a global function with example usage: helper_no_fast_int8_hw_legalization(attrs, inputs, types, relay_op) and returns: relay_op