Bug 106071 - single where run error
Summary: single where run error
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 12.1.0
: P4 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-06-24 06:57 UTC by han.wu
Modified: 2022-06-26 18:36 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-06-24 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description han.wu 2022-06-24 06:57:37 UTC
two layer where work ok, why single where work error? 

example one:

program test
  real :: x(3) = 1, y(3) = 2
  logical :: m(3) = .true., m2(3) = .false.
  where (m)
    x = f1()
    !where (m2)
    !  y = f2()
    !end where
  end where
  if (any(x/=3)) then
    print *, 'FAIL', x
  !if (any(x/=3 .or. y/=3)) then
  !  print *,'FAIL',x,y
  else
    print *,'ok'
  end if
contains
  function f1()
    m = .false.
    !m2 = .true.
    f1 = 3
  end function
  !function f2()
  !  m2 = .false.
  !  f2 = 3
  !end function
end

gfortran-12:
ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
 FAIL   3.00000000       1.00000000       1.00000000   

example two:
program test
  real :: x(3) = 1, y(3) = 2
  logical :: m(3) = .true., m2(3) = .false.
  where (m)
    x = f1()
    where (m2)
      y = f2()
    end where
  end where
  if (any(x/=3 .or. y/=3)) then
    print *,'FAIL',x,y
  else
    print *,'ok'
  end if
contains
  function f1()
    m = .false.
    m2 = .true.
    f1 = 3
  end function
  function f2()
    m2 = .false.
    f2 = 3
  end function
end

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
 ok

Looking forward to hearing from you!
Comment 1 kargls 2022-06-24 14:31:58 UTC
(In reply to han.wu from comment #0)
> two layer where work ok, why single where work error? 
> 

Clearly a bug due to calling a function with side effects.  While valid, it is a questionable programming style.
Comment 2 kargls 2022-06-26 18:36:32 UTC
(In reply to han.wu from comment #0)
> two layer where work ok, why single where work error? 
> 
> example one:
> 
> program test
>   real :: x(3) = 1, y(3) = 2
>   logical :: m(3) = .true., m2(3) = .false.
>   where (m)
>     x = f1()
>   end where
>   if (any(x/=3)) then
>     print *, 'FAIL', x
>   else
>     print *,'ok'
>   end if
> contains
>   function f1()
>     m = .false.
>     !m2 = .true.
>     f1 = 3
>   end function
> end
> 
> gfortran-12:
> ASM generation compiler returned: 0
> Execution build compiler returned: 0
> Program returned: 0
>  FAIL   3.00000000       1.00000000       1.00000000   
> 

Well, this is simple to understand.  The WHERE is eventually translated by
gfc_trans_where_3() from trans-stmt.cc.  What is essentially happening is
that (in pseudo-code) the WHERE is converted to


do i = 1, size(m)
   if (m(i)) then
      m = .false.   ! This resets all elements of m!
      x(i) = 3
   end if
end do

where I have in-lined the function f1.  Looking in gfc_trans_where_3() we see
that gfortran should create a temporary when scalarizing the mask.  I don't
know how to do that.  When you come up with a patch, can you submit it?