Quantization scale verification to prevent spurious tf-tfl conversion
I am tagging @pkgoogle  as he was so kind to advice me on #62196. 

I worked on the bug and created a draft PR. The main culprit for the spurious transformation are the pathological quantization scales. See below for an example of the MLIR debug output:
```
 %22 = "tfl.quantize"(%21) {qtype = tensor<1x64x112x112x!quant.uniform<i8:f32, 1.3344405750530544E+36:127>>, volatile} : (tensor<1x64x112x112xf32>) -> ...
```
I have added a verification check aborting the quantization if the scale parameter exceeds `1e+10`. TF [already considers](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/compiler/mlir/lite/quantization/quantization_utils.h#L307) a quantization scale above `1e+1` problematic, and the [SmoothQuant paper](https://arxiv.org/abs/2211.10438) considers values of `7e+1` (for foundation models) to pose serious challenges. 

The original [gist](https://colab.research.google.com/gist/pjpratik/f71dec9bd1f702c1a62fb8505b7d4a50/62196.ipynb) produces the following output when run with the code from the PR:
```
RuntimeError: Failed to quantize: <unknown>:0: error: loc("PadV2/constant_values"): 'tfl.quantize' op Quant scale (1.334441e+36) too large
<unknown>:0: note: loc("PadV2/constant_values"): see current operation: %4 = "tfl.quantize"(%3) {qtype = tensor<!quant.uniform<i8:f32, 1.3344405750530544E+36:127>>, volatile} : (tensor<f32>) -> tensor<!quant.uniform<i8:f32, 1.3344405750530544E+36:127>>
```

The draft PR also contains a test. In addition to the submitted code, I would still like to add the following:
- Tests for `tfl.quantize` with `UniformQuantizedPerAxisType` quantization
- Verifier for DequantizeOp and associated tests
- End2End tests?

Before adding the functionality above, I would like to ask you two questions for clarification: 
- Do you agree with the broad contours of this PR, or have suggestions? 
- The tests I added (`@satisfy{violate}Threshold`)do not produce any output. (Verify this by running `./bazel-bin/tensorflow/compiler/mlir/tf-opt  -verify-diagnostics -tfl-runtime-verify tensorflow/compiler/mlir/lite/tests/ops.mlir > ops_output.mlir` and see that the tests are missing). I'm surprised by this but realize that `@testQuantizedResizeNearestNeighbor` does not produce output, while `@testQuantize` does. Can you explain the different behavior of the two tests, what I need to do for @satisfyThreshold to be printed, and (just for my understanding) what utility the test of @testQuantizedResizeNearestNeighbor has if it does not produce any output?

I am also tagging @jpienaar  here. He kindly answered an [MLIR question](https://discourse.llvm.org/t/what-impact-does-a-failing-op-verifier-have-on-the-optimization-process/75450) I had, and I thought it might be worthwhile to add him too. 


 Hi @FabianSchuetze, Thank you for your hard work and dedication. I'm trying to understand the root cause a little bit better, so in the original model pre-quantization all the float32's are essentially in the 10^-36 range so our calculated quantization scale to invert that is essentially in the 10^36 range, which when paired with reduced precision in the quantized realm, causes issues. Is my understanding more or less correct there? Hi @pkgoogle : Thanks a lot for your reply! I didn't get to work on this issue in the last days, but will do so soon and answer your questions.  Thanks for your comment & question, @pkgoogle . Thanks to it, I have identified the source of the bug, and we can now reproduce it in a stylized program. 

Please see the first cell of this [gist](https://colab.research.google.com/drive/1Jr6StaZEFJexUtBk98riYEUK617a-eDb?usp=sharing). The three aspects explaining the bug are:

Network Architecture:
- The program has a pad operation with a constant of ~ -3.4e+38 (lowest float32) directly before a maxpool operation. 
- The padding constant does not get fused with the maxpool operation by the compiler. In the model described here, the maxpool filter size exceeds the padding size. Thus, the padded constants get lost in the maxpool. 

During Quantization:
- The padding constant gets quantized: - 3.4e+38 ~ 1.ee+36 * (q - 127) with quantized value of q=-128.  
- The quantization parameters get propagated to subsequent layers.

Upon Loading:
- The quantized add operation [gets parameterized](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/add.cc#L88): The scales of the inputs get loaded and violate their constraint that the "real_output_multiplier" is [below one](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/add.cc#L197) upon which the program aborts. 

I think these three aspects can explain the bug. 

Nevertheless, I am surprised that the maxpool output has such a large scaling parameter. Consider the second cell of the gist. It prints the extrema of the input and output tensors of the maxpool operator:
```
Extrema Maxpool Inp 3.402823E+38, Output: 9.999899E-01
Extrema Maxpool Inp 3.402823E+38, Output: 9.999982E-01
Extrema Maxpool Inp 3.402823E+38, Output: 9.999997E-01
```
The padding value explains the large (absolute values) of the input. The output is small because the maxpool absorbs the negative padding constants. Might this be worth to investigate?  Hi @abattery, may you add any insight here? Hi @abattery Any update on this PR? Please. Thank you! Would also be interested in a feedback and also willing to continue work on this once I’ve heard some feedback . Thanks  Hi @abattery Any update on this PR? Please. Thank you! Hi @abattery Any update on this PR? Please. Thank you! This is similar to the other issue which produced this change: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/sub.cc#L156. In that case the quantization scale was considered "valid" so we let the check through i.e. allowed it to be > 1. I haven't completely reviewed the case here, but if it is "valid" then we can allow it through as well.
Addresses https://github.com/tensorflow/tensorflow/issues/62196

In some situations, the tf-tfl converter can produce spurious quantization scales. The conversion nevertheless passes, but the tensorflow lite interpreter aborts when allocating tensors for the model. The PR adds a verification check for the mlir QuantOps (and DequantizeOps) ops.