blob: bdc96751b8708c6a45c5cc1b28755651419523da [file] [edit]
! Test lowering of parenthesized initial values in fir.global initializer
! regions.
!
! Initial values are lowered through ConvertConstant, which folds a
! parenthesized scalar or derived constant to a plain constant: no
! fir.no_reassoc operation is emitted inside the global init region. (An earlier
! baseline of this test pinned the previous behavior, where a parenthesized
! constant survived folding as a Parentheses node and lowered to a
! fir.no_reassoc.) The forms whose parentheses are stripped before lowering
! (character, array named-constant, and parenthesized structure-constructor
! components) are unaffected and pinned here belt-and-braces.
!
! Each case is a SAVE'd local in its own subroutine so that the fir.global for
! it is emitted in source order, keeping every CHECK block next to the Fortran
! it checks. The --implicit-check-not on the RUN line asserts that no
! fir.no_reassoc is emitted for any of the parenthesized initializers.
! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s --implicit-check-not=fir.no_reassoc
module types
type t
integer :: n
end type t
type t2
! Parenthesized component default initializer.
integer :: n = (5)
end type t2
end module types
subroutine scalar_int()
integer, save :: i = (42)
end subroutine
! CHECK-LABEL: fir.global internal @_QFscalar_intEi : i32 {
! CHECK: %[[C:.*]] = arith.constant 42 : i32
! CHECK: fir.has_value %[[C]] : i32
subroutine nested_parens()
! Stacked parentheses: exercises the recursive descent through nested
! Parentheses<T> nodes.
integer, save :: n2 = ((42))
end subroutine
! CHECK-LABEL: fir.global internal @_QFnested_parensEn2 : i32 {
! CHECK: %[[C:.*]] = arith.constant 42 : i32
! CHECK: fir.has_value %[[C]] : i32
subroutine scalar_real()
real, save :: r = (3.5)
end subroutine
! CHECK-LABEL: fir.global internal @_QFscalar_realEr : f32 {
! CHECK: %[[C:.*]] = arith.constant 3.500000e+00 : f32
! CHECK: fir.has_value %[[C]] : f32
subroutine scalar_logical()
logical, save :: l = (.true.)
end subroutine
! CHECK-LABEL: fir.global internal @_QFscalar_logicalEl : !fir.logical<4> {
! CHECK: %[[C:.*]] = arith.constant true
! CHECK: %[[CV:.*]] = fir.convert %[[C]] : (i1) -> !fir.logical<4>
! CHECK: fir.has_value %[[CV]] : !fir.logical<4>
subroutine scalar_complex()
! Double parentheses so the initializer exercises a Parentheses node rather
! than plain complex-literal syntax.
complex, save :: z = ((1.0, 2.0))
end subroutine
! CHECK-LABEL: fir.global internal @_QFscalar_complexEz : complex<f32> {
! CHECK: fir.insert_value
! CHECK: %[[IV:.*]] = fir.insert_value
! CHECK: fir.has_value %[[IV]] : complex<f32>
subroutine paren_ctor()
use types
! Parenthesized structure constructor: folded to a plain insert_value chain.
type(t), save :: x = (t(7))
end subroutine
! CHECK-LABEL: fir.global internal @_QFparen_ctorEx : !fir.type<_QMtypesTt{n:i32}> {
! CHECK: %[[IV:.*]] = fir.insert_value %{{.*}}, %{{.*}}, ["n", !fir.type<_QMtypesTt{n:i32}>]
! CHECK: fir.has_value %[[IV]] : !fir.type<_QMtypesTt{n:i32}>
subroutine paren_derived_named_const()
use types
! Parenthesized derived named constant: the parentheses wrap a
! Constant<SomeDerived> rather than a structure constructor.
type(t), parameter :: tp = t(3)
type(t), save :: pt2 = (tp)
end subroutine
! (The named constant tp also gets its own constant global; its position
! relative to pt2's global is unpinned.)
! CHECK-LABEL: fir.global internal @_QFparen_derived_named_constEpt2 : !fir.type<_QMtypesTt{n:i32}> {
! CHECK: %[[C:.*]] = arith.constant 3 : i32
! CHECK: %[[IV:.*]] = fir.insert_value %{{.*}}, %[[C]], ["n", !fir.type<_QMtypesTt{n:i32}>]
! CHECK: fir.has_value %[[IV]] : !fir.type<_QMtypesTt{n:i32}>
subroutine comp_default()
use types
! Default-initialized object exercising the parenthesized component default:
! folded to a plain component value.
type(t2), save :: w
end subroutine
! CHECK-LABEL: fir.global internal @_QFcomp_defaultEw : !fir.type<_QMtypesTt2{n:i32}> {
! CHECK: %[[C:.*]] = arith.constant 5 : i32
! CHECK: %[[IV:.*]] = fir.insert_value %{{.*}}, %[[C]], ["n", !fir.type<_QMtypesTt2{n:i32}>]
! CHECK: fir.has_value %[[IV]] : !fir.type<_QMtypesTt2{n:i32}>
subroutine char_paren()
! Belt-and-braces: parentheses stripped before lowering.
character(2), save :: c = ('ab')
end subroutine
! CHECK-LABEL: fir.global internal @_QFchar_parenEc : !fir.char<1,2> {
! CHECK: %[[S:.*]] = fir.string_lit "ab"(2) : !fir.char<1,2>
! CHECK: fir.has_value %[[S]] : !fir.char<1,2>
subroutine array_named_const()
! Parenthesized array named-constant: parentheses stripped, dense global.
integer, parameter :: iparm(2) = [1, 2]
integer, save :: a(2) = (iparm)
end subroutine
! CHECK: fir.global internal @_QFarray_named_constEa(dense<[1, 2]> : tensor<2xi32>) {{.*}} : !fir.array<2xi32>
subroutine paren_ctor_comp()
use types
! Parenthesized structure-constructor component: parentheses stripped, plain
! insert_value chain.
type(t), save :: y = t((5))
end subroutine
! CHECK-LABEL: fir.global internal @_QFparen_ctor_compEy : !fir.type<_QMtypesTt{n:i32}> {
! CHECK: %[[IV:.*]] = fir.insert_value %{{.*}}, %{{.*}}, ["n", !fir.type<_QMtypesTt{n:i32}>]
! CHECK: fir.has_value %[[IV]] : !fir.type<_QMtypesTt{n:i32}>