This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR fortran/83998 -- fix dot_product on 0-sized arrays


On Thu, Jan 25, 2018 at 08:37:54AM +0100, Thomas Koenig wrote:
> First, why is
> 
> > @@ -2253,22 +2253,19 @@ gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
> >   gfc_expr*
> >   gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
> >   {
> > +  /* If vector_a is a zero-sized array, the result is 0 for INTEGER,
> > +     REAL, and COMPLEX types and .false. for LOGICAL.  */
> > +  if (vector_a->shape && mpz_get_si (vector_a->shape[0]) == 0)
> > +    {
> > +      if (vector_a->ts.type == BT_LOGICAL)
> > +	return gfc_get_logical_expr (gfc_default_logical_kind, NULL, false);
> > +      else
> > +	return gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
> > +    }
> 
> in front of

There are two problems with is_constant_array_expr.  First,
it doesn't handle zero-sized arrays.  It returns false, and
dot_product(a,a,) is not simplified.  The dot_product reaches
gfc_conv_intrinsic_dot_product, which tries to generate
in-line code, except it isn't prepared to deal with zero-sized
arrays and ICE occurs.  Second, with the code of the testcase
on entering gfc_simplify_dot_product, we have

vector_a->expr_type == EXPR_VARIABLE
vector_a->rank == 1
vector_a->shape == some_valid_pointer.

after is_constant_array_expr is called we have

vector_a->expr_type == EXPR_CONSTANT
vector_a->rank == 1
vector_a->shape == NULL.

This NULL does not play well gfc_conv_intrinsic_dot_product().
The testcase code arrives here where some_valid_pointer points
to a GMP entity with a value of 0, i.e., a zero-sized array.
So, gfortran can simplify dot_product as I have done
above.

> > -  gfc_expr temp;
> > -
> >     if (!is_constant_array_expr (vector_a)
> >         || !is_constant_array_expr (vector_b))
> >       return NULL;
> 
> and / or why is the test only done for one variable?

gfc_check_dot_product checks that shape of vector_a
and shape of vector_b are the same.  If vector_a is zero
sized, then so is vector_b.

> 
> Second, why do you remove this
> 
> > -  temp.value.op.op = INTRINSIC_NONE;
> > -  temp.value.op.op1 = vector_a;
> > -  temp.value.op.op2 = vector_b;
> > -  gfc_type_convert_binary (&temp, 1);
> 
> block of code?

It is dead code.  temp is set to the typespec of 
the mixed-mode math result, but it is never used.
compute_dot_product does the mixed-mode math,
because it uses gfc_add() from arith.c.

> What would happen for code like
> 
>    integer, dimension(2), parameter :: a = [ 1,2]
>    real, dimension(2), parameter :: b = [1.0,2.0]
>    real, parameter :: c = dot_product(a,b)

gfortran rejects it as it isn't a valid Fortran unit.  :-)

gfcx -fdump-tree-original -o z a.f90 && ./z
   5.00000000    

cat a.f90.003t.original
  {
    struct __st_parameter_dt dt_parm.0;

    dt_parm.0.common.filename = &"a.f90"[1]{lb: 1 sz: 1};
    dt_parm.0.common.line = 4;
    dt_parm.0.common.flags = 128;
    dt_parm.0.common.unit = 6;
    _gfortran_st_write (&dt_parm.0);
    {
      static real(kind=4) C.3752 = 5.0e+0;

      _gfortran_transfer_real_write (&dt_parm.0, &C.3752, 4);
    }
    _gfortran_st_write_done (&dt_parm.0);
  }

-- 
Steve


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]