[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PULL 06/29] softfloat: Move compare_floats to softfloat-parts.c.inc
|
From: |
Peter Maydell |
|
Subject: |
Re: [PULL 06/29] softfloat: Move compare_floats to softfloat-parts.c.inc |
|
Date: |
Thu, 31 Mar 2022 11:46:35 +0100 |
On Thu, 3 Jun 2021 at 22:49, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Rename to parts$N_compare. Rename all of the intermediate
> functions to ftype_do_compare. Rename the hard-float functions
> to ftype_hs_compare. Convert float128 to FloatParts128.
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
I was wading through some of this code trying to figure out
whether some of Coverity's new issues are false positives, and
noticed something odd about this old commit:
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 4fee5a6cb7..6f1bbbe6cf 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -882,6 +882,14 @@ static FloatParts128 *parts128_minmax(FloatParts128 *a,
> FloatParts128 *b,
> #define parts_minmax(A, B, S, F) \
> PARTS_GENERIC_64_128(minmax, A)(A, B, S, F)
>
> +static int parts64_compare(FloatParts64 *a, FloatParts64 *b,
> + float_status *s, bool q);
> +static int parts128_compare(FloatParts128 *a, FloatParts128 *b,
> + float_status *s, bool q);
Here we define these two functions as returning "int"...
> +static FloatRelation QEMU_FLATTEN
> +float16_do_compare(float16 a, float16 b, float_status *s, bool is_quiet)
> {
> + float16_unpack_canonical(&pa, a, s);
> + float16_unpack_canonical(&pb, b, s);
> + return parts_compare(&pa, &pb, s, is_quiet);
> }
...but here we use the return value directly in a function
that returns a FloatRelation...
> diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
> index b9094768db..3dacb5b4f0 100644
> --- a/fpu/softfloat-parts.c.inc
> +++ b/fpu/softfloat-parts.c.inc
> @@ -1018,3 +1018,60 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a,
> FloatPartsN *b,
> }
> return cmp < 0 ? b : a;
> }
> +
> +/*
> + * Floating point compare
> + */
> +static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
> + float_status *s, bool is_quiet)
> +{
...and unless I'm getting confused by the macro usage here,
the actual definition of the functions returns a FloatRelation.
(I'm not sure why the compiler doesn't complain about the mismatch.)
> + int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);
> + int cmp;
> +
> + if (likely(ab_mask == float_cmask_normal)) {
> + if (a->sign != b->sign) {
> + goto a_sign;
> + }
> + if (a->exp != b->exp) {
> + cmp = a->exp < b->exp ? -1 : 1;
> + } else {
> + cmp = frac_cmp(a, b);
> + }
> + if (a->sign) {
> + cmp = -cmp;
> + }
> + return cmp;
This code path seems to be written to assume an
integer -1 or 1 return value...
> + }
> +
> + if (unlikely(ab_mask & float_cmask_anynan)) {
> + if (!is_quiet || (ab_mask & float_cmask_snan)) {
> + float_raise(float_flag_invalid, s);
> + }
> + return float_relation_unordered;
> + }
> +
> + if (ab_mask & float_cmask_zero) {
> + if (ab_mask == float_cmask_zero) {
> + return float_relation_equal;
> + } else if (a->cls == float_class_zero) {
> + goto b_sign;
> + } else {
> + goto a_sign;
> + }
> + }
> +
> + if (ab_mask == float_cmask_inf) {
> + if (a->sign == b->sign) {
> + return float_relation_equal;
...but code later in the function works with and returns the
float_relation_* enumeration values.
> + }
> + } else if (b->cls == float_class_inf) {
> + goto b_sign;
> + } else {
> + g_assert(a->cls == float_class_inf);
> + }
> +
> + a_sign:
> + return a->sign ? float_relation_less : float_relation_greater;
> + b_sign:
> + return b->sign ? float_relation_greater : float_relation_less;
> +}
FWIW, the Coverity issues are CID 1487134, 1487139, 1487151, 1487184,
where for some reason it thinks that floatx80_compare() and
floatx80_compare_quiet() can return 3 and thus that there is a
potential array overrun. (I've marked these all as false positives
in the UI, anyway.)
thanks
-- PMM
- Re: [PULL 06/29] softfloat: Move compare_floats to softfloat-parts.c.inc,
Peter Maydell <=