This is an archive of the discontinued LLVM Phabricator instance.

[flang] Initial lowering of SELECT TYPE construct to fir.select_type operation
ClosedPublic

Authored by clementval on Nov 9 2022, 11:58 AM.

Details

Summary

This patch is the initial path to lower the SELECT TYPE construct to the
fir.select_type operation. More work is required in the AssocEntity
mapping but it will be done in a follow up patch to ease the review.

Diff Detail

Event Timeline

clementval created this revision.Nov 9 2022, 11:58 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptNov 9 2022, 11:58 AM
Herald added a subscriber: mehdi_amini. · View Herald Transcript
clementval requested review of this revision.Nov 9 2022, 11:58 AM
PeteSteinfeld requested changes to this revision.Nov 9 2022, 12:23 PM

Things generally build and look correct, but when I run check-flang, I get a failure:

******************** TEST 'Flang :: Lower/module_use.f90' FAILED ********************
Script:
--
: 'RUN: at line 1';   bbc -emit-fir /local/home/psteinfeld/main/select/flang/test/Lower/module_definition.f90
: 'RUN: at line 2';   bbc -emit-fir /local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90 -o - | /local/home/psteinfeld/main/select/build/bin/FileCheck /local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90
--
Exit Code: 1

Command Output (stderr):
--
/local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90:15:15: error: CHECK-DAG: expected string not found in input
 ! CHECK-DAG: fir.address_of(@_QMm1Ex) : !fir.ref<f32>
              ^
<stdin>:4:22: note: scanning from here
func.func @_QPm1use() -> f32 {
                     ^
<stdin>:13:2: note: possible intended match here
 fir.store %5 to %1 : !fir.ref<f32>
 ^
/local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90:42:14: error: CHECK-DAG: expected string not found in input
! CHECK-DAG: fir.global @_QMm1Ex : f32
             ^
<stdin>:17:30: note: scanning from here
func.func @_QPmodcommon1use() -> f32 {
                             ^
<stdin>:36:17: note: possible intended match here
 %15 = arith.addf %13, %14 : f32
                ^

Input file: <stdin>
Check file: /local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90

-dump-input=help explains the following input dump.

Input was:
<<<<<<
          1: fir.global common @_QB(dense<0> : vector<4xi8>) : !fir.array<4xi8> 
          2: fir.global common @_QBnamed1(dense<0> : vector<4xi8>) : !fir.array<4xi8> 
          3: fir.global common @_QBnamed2(dense<0> : vector<4xi8>) : !fir.array<4xi8> 
          4: func.func @_QPm1use() -> f32 { 
dag:15'0                          X~~~~~~~~~ error: no match found
          5:  %0 = fir.alloca i32 {adapt.valuebyref} 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          6:  %1 = fir.alloca f32 {bindc_name = "m1use", uniq_name = "_QFm1useEm1use"} 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          7:  %2 = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFm1useEx"} 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          8:  %3 = fir.load %2 : !fir.ref<f32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          9:  %c1_i32 = arith.constant 1 : i32 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         10:  fir.store %c1_i32 to %0 : !fir.ref<i32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         11:  %4 = fir.call @_QPy(%0) : (!fir.ref<i32>) -> f32 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         12:  %5 = arith.addf %3, %4 : f32 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         13:  fir.store %5 to %1 : !fir.ref<f32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dag:15'1      ?                                   possible intended match
         14:  %6 = fir.load %1 : !fir.ref<f32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         15:  return %6 : f32 
dag:15'0     ~~~~~~~~~~~~~~~~~
         16: } 
dag:15'0     ~~
         17: func.func @_QPmodcommon1use() -> f32 { 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dag:42'0                                  X~~~~~~~~~ error: no match found
         18:  %0 = fir.address_of(@_QBnamed2) : !fir.ref<!fir.array<4xi8>> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         19:  %1 = fir.convert %0 : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         20:  %c0 = arith.constant 0 : index 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         21:  %2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         22:  %3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<i32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          .
          .
          .
         31:  %c0_1 = arith.constant 0 : index 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         32:  %11 = fir.coordinate_of %10, %c0_1 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         33:  %12 = fir.convert %11 : (!fir.ref<i8>) -> !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         34:  %13 = fir.load %8 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         35:  %14 = fir.load %12 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         36:  %15 = arith.addf %13, %14 : f32 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dag:42'1                     ?                 possible intended match
         37:  %16 = fir.load %3 : !fir.ref<i32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         38:  %17 = fir.convert %16 : (i32) -> f32 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         39:  %18 = arith.addf %15, %17 : f32 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         40:  fir.store %18 to %4 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         41:  %19 = fir.load %4 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          .
          .
          .
>>>>>>

--

********************
This revision now requires changes to proceed.Nov 9 2022, 12:23 PM

Things generally build and look correct, but when I run check-flang, I get a failure:

******************** TEST 'Flang :: Lower/module_use.f90' FAILED ********************
Script:
--
: 'RUN: at line 1';   bbc -emit-fir /local/home/psteinfeld/main/select/flang/test/Lower/module_definition.f90
: 'RUN: at line 2';   bbc -emit-fir /local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90 -o - | /local/home/psteinfeld/main/select/build/bin/FileCheck /local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90
--
Exit Code: 1

Command Output (stderr):
--
/local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90:15:15: error: CHECK-DAG: expected string not found in input
 ! CHECK-DAG: fir.address_of(@_QMm1Ex) : !fir.ref<f32>
              ^
<stdin>:4:22: note: scanning from here
func.func @_QPm1use() -> f32 {
                     ^
<stdin>:13:2: note: possible intended match here
 fir.store %5 to %1 : !fir.ref<f32>
 ^
/local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90:42:14: error: CHECK-DAG: expected string not found in input
! CHECK-DAG: fir.global @_QMm1Ex : f32
             ^
<stdin>:17:30: note: scanning from here
func.func @_QPmodcommon1use() -> f32 {
                             ^
<stdin>:36:17: note: possible intended match here
 %15 = arith.addf %13, %14 : f32
                ^

Input file: <stdin>
Check file: /local/home/psteinfeld/main/select/flang/test/Lower/module_use.f90

-dump-input=help explains the following input dump.

Input was:
<<<<<<
          1: fir.global common @_QB(dense<0> : vector<4xi8>) : !fir.array<4xi8> 
          2: fir.global common @_QBnamed1(dense<0> : vector<4xi8>) : !fir.array<4xi8> 
          3: fir.global common @_QBnamed2(dense<0> : vector<4xi8>) : !fir.array<4xi8> 
          4: func.func @_QPm1use() -> f32 { 
dag:15'0                          X~~~~~~~~~ error: no match found
          5:  %0 = fir.alloca i32 {adapt.valuebyref} 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          6:  %1 = fir.alloca f32 {bindc_name = "m1use", uniq_name = "_QFm1useEm1use"} 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          7:  %2 = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFm1useEx"} 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          8:  %3 = fir.load %2 : !fir.ref<f32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          9:  %c1_i32 = arith.constant 1 : i32 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         10:  fir.store %c1_i32 to %0 : !fir.ref<i32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         11:  %4 = fir.call @_QPy(%0) : (!fir.ref<i32>) -> f32 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         12:  %5 = arith.addf %3, %4 : f32 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         13:  fir.store %5 to %1 : !fir.ref<f32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dag:15'1      ?                                   possible intended match
         14:  %6 = fir.load %1 : !fir.ref<f32> 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         15:  return %6 : f32 
dag:15'0     ~~~~~~~~~~~~~~~~~
         16: } 
dag:15'0     ~~
         17: func.func @_QPmodcommon1use() -> f32 { 
dag:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dag:42'0                                  X~~~~~~~~~ error: no match found
         18:  %0 = fir.address_of(@_QBnamed2) : !fir.ref<!fir.array<4xi8>> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         19:  %1 = fir.convert %0 : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         20:  %c0 = arith.constant 0 : index 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         21:  %2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         22:  %3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<i32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          .
          .
          .
         31:  %c0_1 = arith.constant 0 : index 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         32:  %11 = fir.coordinate_of %10, %c0_1 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         33:  %12 = fir.convert %11 : (!fir.ref<i8>) -> !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         34:  %13 = fir.load %8 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         35:  %14 = fir.load %12 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         36:  %15 = arith.addf %13, %14 : f32 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dag:42'1                     ?                 possible intended match
         37:  %16 = fir.load %3 : !fir.ref<i32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         38:  %17 = fir.convert %16 : (i32) -> f32 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         39:  %18 = arith.addf %15, %17 : f32 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         40:  fir.store %18 to %4 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         41:  %19 = fir.load %4 : !fir.ref<f32> 
dag:42'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          .
          .
          .
>>>>>>

--

********************

That looks weird. I’ll try to reproduce but so far I do not have this failure on my side.

Update test module name to avoid collision.

@PeteSteinfeld The problem was coming from a collision between the module names. The module in flang/test/Lower/select-type.f90 was m1 and also in the tests checking for module use.

Mostly questions to clarify what is final and what will change in the future mapping (given the tests, I expect array are not intended to be covered here, and most of my questions are about this). Looks great otherwise.

flang/lib/Lower/Bridge.cpp
2120

This will hopefully get a bit simpler in the future with the updated lowering, but I think getExprAddr might not be the right thing to call since I believe that it would cause assumed shape polymorphic to be copied into a contiguous temp... genExprBox might be what is needed here instead.
genExprBox will cause POINTER/ALLOCATABLEs to be dereferenced, but as I understand from the standard, this is not an issue in SELECT TYPE since the associated entity does not have the POINTER/ALLOCATABLE attributes as per 11.1.3.3.

2206

That's a clever way to find the scope !

2214

You may be aware of this since you mention more needs to be done for the mapping, but the lower bounds may be incorrect since they are dropped on the floor whenever going from from an fir::ExtendedValue to an mlir::Value via fir::getBase(). You would need to keep the selector as a fir::ExtendedValue to keep them.

2215

nit: extra braces around the if (except if you wanted to add a break;) and for

2231

This only makes sense if the variable is a scalar, right ? Is the array part planned in another patch ?

2241

Don't you need to convert to a more refined class type here too ?

Mostly questions to clarify what is final and what will change in the future mapping (given the tests, I expect array are not intended to be covered here, and most of my questions are about this). Looks great otherwise.

Thanks for the review. I'll update the patch today. As you mentioned, array are not covered yet in this patch.

flang/lib/Lower/Bridge.cpp
2120

Good to know. I'll update that.

2214

Yes, array are not supported yet.

2231

Yes. For array there is more work needed and we will likely keep the descriptor around.

2241

I did not see any use cases where it would be useful but I might when I can run more tests on this.

jeanPerier added inline comments.Nov 10 2022, 7:33 AM
flang/lib/Lower/Bridge.cpp
2241

Isn't it needed if there is an access to one of the type guard's type component that is not a component of the selector type ?

I expect lowering would have troubles issuing a fir.coordinate for a field if it is not part of the static type of the base.

module test
type t1
 integer :: i
end type
type, extends(t1) :: t2
  integer :: j
end type
contains
subroutine print_if_has_j(a)
  class(t1) :: a
  select type (a)
  class is (t2)
    print *, a%j
  class default
    print *, "has no j member"
  end select
end subroutine
end module
clementval marked 5 inline comments as done.

Address review comments

flang/lib/Lower/Bridge.cpp
2241

Correct. Updated.

Fix exit with no default

This revision was not accepted when it landed; it landed in state Needs Review.Nov 14 2022, 1:48 AM
This revision was automatically updated to reflect the committed changes.