Skip to content

Commit

Permalink
[flang][NFC] Add more lowering tests
Browse files Browse the repository at this point in the history
This patch adds more lowering tests from the PFT to FIR.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D122354

Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
  • Loading branch information
3 people committed Mar 23, 2022
1 parent 805899e commit b914efc
Show file tree
Hide file tree
Showing 7 changed files with 421 additions and 0 deletions.
11 changes: 11 additions & 0 deletions flang/test/Lower/complex-part.f90
@@ -0,0 +1,11 @@
! RUN: bbc %s -o - | tco | FileCheck %s

COMPLEX c
c%RE = 3.14
CALL sub(c)
END

! Verify that the offset in the struct does not regress from i32.
! CHECK-LABEL: define void @_QQmain()
! CHECK: getelementptr { float, float }, { float, float }* %{{[0-9]+}}, i64 0, i32 0

18 changes: 18 additions & 0 deletions flang/test/Lower/computed-goto.f90
@@ -0,0 +1,18 @@
! RUN: bbc -emit-fir -o - %s | FileCheck %s

! CHECK-LABEL: func @_QPm
function m(index)
! CHECK: fir.select %{{.}} : i32 [1, ^bb{{.}}, 2, ^bb{{.}}, 3, ^bb{{.}}, 4, ^bb{{.}}, 5, ^bb{{.}}, unit, ^bb{{.}}]
goto (9,7,5,3,1) index ! + 1
m = 0; return
1 m = 1; return
3 m = 3; return
5 m = 5; return
7 m = 7; return
9 m = 9; return
end

! print*, m(-3); print*, m(0)
! print*, m(1); print*, m(2); print*, m(3); print*, m(4); print*, m(5)
! print*, m(6); print*, m(9)
end
25 changes: 25 additions & 0 deletions flang/test/Lower/control-flow.f90
@@ -0,0 +1,25 @@
! Tests for control-flow

! RUN: bbc -emit-fir %s -o - | FileCheck %s

! check the lowering of a RETURN in the body of a SUBROUTINE
! CHECK-LABEL one
subroutine one(a,b,c)
d = 1.0
if (a .ne. b) then
! CHECK: call @_QPone_a
call one_a(d)
! CHECK: cond_br %{{.*}}, ^bb[[TB:.*]], ^
if (d .eq. 1.0) then
! CHECK-NEXT: ^bb[[TB]]:
! CHECK-NEXT: br ^bb[[EXIT:.*]]
return
endif
else
e = 4.0
call one_b(c,d,e)
endif
! CHECK: ^bb[[EXIT]]:
! CHECK-NEXT: return
end subroutine one

177 changes: 177 additions & 0 deletions flang/test/Lower/default-initialization.f90
@@ -0,0 +1,177 @@
! Test default initialization of local and dummy variables (dynamic initialization)
! RUN: bbc -emit-fir %s -o - | FileCheck %s

module test_dinit
type t
integer :: i = 42
end type
type t_alloc_comp
real, allocatable :: i(:)
end type
type tseq
sequence
integer :: i = 42
end type
contains

! -----------------------------------------------------------------------------
! Test default initialization of local and dummy variables.
! -----------------------------------------------------------------------------

! Test local scalar is default initialized
! CHECK-LABEL: func @_QMtest_dinitPlocal()
subroutine local
! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}>
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
type(t) :: x
print *, x%i
end subroutine

! Test local array is default initialized
! CHECK-LABEL: func @_QMtest_dinitPlocal_array()
subroutine local_array()
! CHECK: %[[x:.*]] = fir.alloca !fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>
! CHECK: %[[xshape:.*]] = fir.shape %c4{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshape]]) : (!fir.ref<!fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>>
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
type(t) :: x(4)
print *, x(2)%i
end subroutine

! Test allocatable component triggers default initialization of local
! scalars.
! CHECK-LABEL: func @_QMtest_dinitPlocal_alloc_comp()
subroutine local_alloc_comp
! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.box<!fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
type(t_alloc_comp) :: x
end subroutine

! Test function results are default initialized.
! CHECK-LABEL: func @_QMtest_dinitPresult() -> !fir.type<_QMtest_dinitTt{i:i32}>
function result()
! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}>
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
type(t) :: result
end function

! Test intent(out) dummies are default initialized
! CHECK-LABEL: func @_QMtest_dinitPintent_out(
! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
subroutine intent_out(x)
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
type(t), intent(out) :: x
end subroutine

! Test that optional intent(out) are default initialized only when
! present.
! CHECK-LABEL: func @_QMtest_dinitPintent_out_optional(
! CHECK-SAME: %[[x:.*]]: !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>> {fir.bindc_name = "x", fir.optional})
subroutine intent_out_optional(x)
! CHECK: %[[isPresent:.*]] = fir.is_present %[[x]] : (!fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>) -> i1
! CHECK: fir.if %[[isPresent]] {
! CHECK: %[[xboxNone:.*]] = fir.convert %[[x]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
! CHECK: }
type(t), intent(out), optional :: x
end subroutine

! Test local equivalences where one entity has default initialization
! CHECK-LABEL: func @_QMtest_dinitPlocal_eq()
subroutine local_eq()
type(tseq) :: x
integer :: zi
! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8>
! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTtseq{i:i32}>>
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
equivalence (x, zi)
print *, i
end subroutine

! Test local equivalences with both equivalenced entities being
! default initialized. Note that the standard allow default initialization
! to be performed several times as long as the values are the same. So
! far that is what lowering is doing to stay simple.
! CHECK-LABEL: func @_QMtest_dinitPlocal_eq2()
subroutine local_eq2()
type(tseq) :: x
type(tseq) :: y
! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8>
! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTtseq{i:i32}>>
! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none


! CHECK: %[[ycoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
! CHECK: %[[y:.*]] = fir.convert %[[ycoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
! CHECK: %[[ybox:.*]] = fir.embox %[[y]] : (!fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTtseq{i:i32}>>
! CHECK: %[[yboxNone:.*]] = fir.convert %[[ybox]]
! CHECK: fir.call @_FortranAInitialize(%[[yboxNone]], %{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<i8>, i32) -> none
equivalence (x, y)
print *, y%i
end subroutine


! -----------------------------------------------------------------------------
! Test for local and dummy variables that must not be initialized
! -----------------------------------------------------------------------------

! CHECK-LABEL: func @_QMtest_dinitPnoinit_local_alloc
subroutine noinit_local_alloc
! CHECK-NOT: fir.call @_FortranAInitialize
type(t), allocatable :: x
! CHECK: return
end subroutine

! CHECK-LABEL: func @_QMtest_dinitPnoinit_local_pointer
subroutine noinit_local_pointer
! CHECK-NOT: fir.call @_FortranAInitialize
type(t), pointer :: x
! CHECK: return
end subroutine

! CHECK-LABEL: func @_QMtest_dinitPnoinit_normal_dummy
subroutine noinit_normal_dummy(x)
! CHECK-NOT: fir.call @_FortranAInitialize
type(t) :: x
! CHECK: return
end subroutine

! CHECK-LABEL: func @_QMtest_dinitPnoinit_intentinout_dummy
subroutine noinit_intentinout_dummy(x)
! CHECK-NOT: fir.call @_FortranAInitialize
type(t), intent(inout) :: x
! CHECK: return
end subroutine

end module

! End-to-end test for debug pruposes.
use test_dinit
type(t) :: at
call local()
call local_array()
at%i = 66
call intent_out(at)
print *, at%i
at%i = 66
call intent_out_optional(at)
print *, at%i
call intent_out_optional()
call local_eq()
call local_eq2()
end
22 changes: 22 additions & 0 deletions flang/test/Lower/dense-attributed-array.f90
@@ -0,0 +1,22 @@
! RUN: bbc --emit-fir %s -o - | FileCheck %s

! Test generation of dense attributed global array. Also, make sure there are
! no dead ssa assignments.
module mm
integer, parameter :: qq(3) = [(i,i=51,53)]
end
subroutine ss
use mm
n = qq(3)
end
!CHECK-NOT: %{{.*}} = fir.undefined !fir.array<3xi32>
!CHECK-NOT: %{{.*}} = arith.constant %{{.*}} : index
!CHECK-NOT: %{{.*}} = arith.constant %{{.*}} : i32
!CHECK-NOT: %{{.*}} = fir.insert_value %{{.*}}, %{{.*}}, [%{{.*}} : index] : (!fir.array<3xi32>, i32) -> !fir.array<3xi32>
!CHECK: fir.global @_QMmmECqq(dense<[51, 52, 53]> : tensor<3xi32>) constant : !fir.array<3xi32>
!CHECK: func @_QPss() {
!CHECK: %[[a0:.*]] = fir.alloca i32 {bindc_name = "n", uniq_name = "_QFssEn"}
!CHECK: %[[c0:.*]] = arith.constant 53 : i32
!CHECK: fir.store %[[c0]] to %[[a0]] : !fir.ref<i32>
!CHECK: return
!CHECK: }

0 comments on commit b914efc

Please sign in to comment.