Bug 43841 - Missing temporary for ELEMENTAL function call
Missing temporary for ELEMENTAL function call
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.6.0
: P3 normal
: ---
Assigned To: Paul Thomas
: wrong-code
: 43843 (view as bug list)
Depends on:
Blocks: 42361
  Show dependency treegraph
 
Reported: 2010-04-21 19:52 UTC by Harald Anlauf
Modified: 2010-06-27 16:24 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.3.2 4.4.0 4.5.0 4.6.0
Last reconfirmed: 2010-04-23 08:12:46


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Harald Anlauf 2010-04-21 19:52:57 UTC
As reported in

http://gcc.gnu.org/ml/fortran/2010-04/msg00215.html

gfortran does not always produce a temporary when it deems necessary.

Reduce testcase:

program main
  implicit none

  type::polar_t
     real :: l
  end type polar_t

  call test_member
contains

  subroutine test_member
    type(polar_t),dimension(2)::b

    b    = polar_t(2.0)
    b(:) = div_pp (b(:), b(1))
    write(*,*) b
    if (b(2)%l /= 1) call abort ()
  end subroutine test_member

  elemental function div_pp(u,v) result(o)
    type(polar_t),intent(in)::u,v
    type(polar_t)           ::o
    o%l  = u%l / v%l
  end function div_pp

end program main

Result with gfortran:
% ./a.out
   1.0000000       2.0000000
Aborted

Expected result:
   1.000000       1.000000
Comment 1 Dominique d'Humieres 2010-04-21 20:48:55 UTC
Confirmed. The test fails with gfortran from at least 4.2.3 up to trunk.
Comment 2 Dominique d'Humieres 2010-04-21 21:51:23 UTC
PR43843 looks like a duplicate.
Comment 3 Harald Anlauf 2010-04-22 07:27:47 UTC
(In reply to comment #2)
> PR43843 looks like a duplicate.

It is.  I simply reduced the program in the mail to a testcase.
Comment 4 Daniel Franke 2010-04-22 08:25:29 UTC
*** Bug 43843 has been marked as a duplicate of this bug. ***
Comment 5 Tobias Burnus 2010-04-22 08:28:12 UTC
From PR 43843:

Reported by Kyle Horne at http://gcc.gnu.org/ml/fortran/2010-04/msg00215.html

There is a missing temporary for user-defined operators:

   type(polar_t),dimension(3)::b
   b = polar_t(1.0,0.5)
   b(:) = b(:)/b(1)

The latter is translated into:
    struct polar_t * D.1551;
    D.1551 = &b[0];

      S.5 = 1;
      while (1)
        {
          if (S.5 > 3) goto L.3;
          b[S.5 + -1] = div_pp (&b[S.5 + -1], D.1551);
          S.5 = S.5 + 1;
        }
      L.3:;

but that fails as one overrides *D.1551 alias b[0] alias B(1) in the first
iteration instead of evaluating first all of the RHS before assigning to the
LHS.

Work with ifort and NAG, fails with GCC 4.1, 4.2, 4.3, 4.4, 4.5, and 4.6
Comment 6 Paul Thomas 2010-04-22 20:01:17 UTC
(In reply to comment #5)

>     struct polar_t * D.1551;
>     D.1551 = &b[0];
> 
>       S.5 = 1;
>       while (1)
>         {
>           if (S.5 > 3) goto L.3;
>           b[S.5 + -1] = div_pp (&b[S.5 + -1], D.1551);
>           S.5 = S.5 + 1;
>         }
>       L.3:;
> 

The temporary is being generated but it needs dereferencing !!! ie. It would be nice if:
>     struct polar_t  D.1551;
>     D.1551 = b[0];
> 
>       S.5 = 1;
>       while (1)
>         {
>           if (S.5 > 3) goto L.3;
>           b[S.5 + -1] = div_pp (&b[S.5 + -1], &D.1551);
>           S.5 = S.5 + 1;
>         }
>       L.3:;
> 

were happening.

Paul

I'm looking at it.

Paul
Comment 7 Paul Thomas 2010-04-23 08:12:45 UTC
I posted a fix this morning.

Paul
Comment 8 Paul Thomas 2010-04-24 07:44:24 UTC
(In reply to comment #7)
> I posted a fix this morning.
...which gives,

  {
    struct polar_t D.1625;

    D.1625 = b[0];
    {
      integer(kind=8) S.18;

      S.18 = 1;
      while (1)
        {
          if (S.18 > 3) goto L.15;
          b[S.18 + -1] = div_pp (&b[S.18 + -1], &D.1625);
          S.18 = S.18 + 1;
        }
      L.15:;
    }
  }
Comment 9 Paul Thomas 2010-04-24 09:28:58 UTC
Subject: Bug 43841

Author: pault
Date: Sat Apr 24 09:28:32 2010
New Revision: 158683

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=158683
Log:
2010-04-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43841
	PR fortran/43843
	* trans-expr.c (gfc_conv_expr): Supply an address expression for
	GFC_SS_REFERENCE.
	(gfc_conv_expr_reference): Call gfc_conv_expr and return for
	GFC_SS_REFERENCE.
	* trans-array.c (gfc_add_loop_ss_code): Store the value rather
	than the address of a GFC_SS_REFERENCE.
	* trans.h : Change comment on GFC_SS_REFERENCE. 

2010-04-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43841
	PR fortran/43843
	* gfortran.dg/elemental_scalar_args_1.f90 : New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/elemental_scalar_args_1.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog

Comment 10 Mikael Morin 2010-05-25 21:02:18 UTC
Any backport ?
Comment 11 Paul Thomas 2010-06-24 15:44:26 UTC
(In reply to comment #10)
> Any backport ?
> 

Ah yes, thanks, Mikael....

I have drawn up a list of PRs for which I have fixes but have not made commits.  I'll try to get through them next week.

Paul
Comment 12 Paul Thomas 2010-06-27 16:15:14 UTC
Subject: Bug 43841

Author: pault
Date: Sun Jun 27 16:14:55 2010
New Revision: 161471

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161471
Log:
2010-06-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43841
	PR fortran/43843
	* trans-expr.c (gfc_conv_expr): Supply an address expression for
	GFC_SS_REFERENCE.
	(gfc_conv_expr_reference): Call gfc_conv_expr and return for
	GFC_SS_REFERENCE.
	* trans-array.c (gfc_add_loop_ss_code): Store the value rather
	than the address of a GFC_SS_REFERENCE.
	* trans.h : Change comment on GFC_SS_REFERENCE. 

2010-06-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43841
	PR fortran/43843
	* gfortran.dg/elemental_scalar_args_1.f90 : New test.


Added:
    branches/gcc-4_5-branch/gcc/testsuite/gfortran.dg/elemental_scalar_args_1.f90
Modified:
    branches/gcc-4_5-branch/gcc/fortran/ChangeLog
    branches/gcc-4_5-branch/gcc/fortran/trans-array.c
    branches/gcc-4_5-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_5-branch/gcc/fortran/trans.h
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog

Comment 13 Paul Thomas 2010-06-27 16:22:43 UTC
Subject: Bug 43841

Author: pault
Date: Sun Jun 27 16:22:27 2010
New Revision: 161472

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161472
Log:
2010-06-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43841
	PR fortran/43843
	* trans-expr.c (gfc_conv_expr): Supply an address expression for
	GFC_SS_REFERENCE.
	(gfc_conv_expr_reference): Call gfc_conv_expr and return for
	GFC_SS_REFERENCE.
	* trans-array.c (gfc_add_loop_ss_code): Store the value rather
	than the address of a GFC_SS_REFERENCE.
	* trans.h : Change comment on GFC_SS_REFERENCE. 

2010-06-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/43841
	PR fortran/43843
	* gfortran.dg/elemental_scalar_args_1.f90 : New test.


Added:
    branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/elemental_scalar_args_1.f90
Modified:
    branches/gcc-4_4-branch/gcc/fortran/ChangeLog
    branches/gcc-4_4-branch/gcc/fortran/trans-array.c
    branches/gcc-4_4-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_4-branch/gcc/fortran/trans.h
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 14 Paul Thomas 2010-06-27 16:24:39 UTC
Fixed and backported to 4.4 and 4.5

Thanks for the report

Paul