llvm-project/flang/test/Lower/select-case-statement.f90
Jonathon Penix a560eea8bb [Flang] Set constructExit for Where and Forall constructs
Evaluations for the Where and Forall constructs previously did
not have their constructExit field fixed up. This could lead to
falling through to subsequent case blocks in select case
statements if either a Where or Forall construct was the final part
of one case block. Setting the constructExit field results in the
proper branching behavior.

Fixes issue: https://github.com/llvm/llvm-project/issues/56500

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

Change-Id: Ia868df12084520a935f087524e118bcdf47f6d7a
2022-07-15 12:34:28 -07:00

400 lines
12 KiB
Fortran

! RUN: bbc -emit-fir -o - %s | FileCheck %s
! CHECK-LABEL: sinteger
function sinteger(n)
integer sinteger
nn = -88
! CHECK: fir.select_case {{.*}} : i32
! CHECK-SAME: upper, %c1
! CHECK-SAME: point, %c2
! CHECK-SAME: point, %c3
! CHECK-SAME: interval, %c4{{.*}} %c5
! CHECK-SAME: point, %c6
! CHECK-SAME: point, %c7
! CHECK-SAME: interval, %c8{{.*}} %c15
! CHECK-SAME: lower, %c21
! CHECK-SAME: unit
select case(n)
case (:1)
nn = 1
case (2)
nn = 2
case default
nn = 0
case (3)
nn = 3
case (4:5+1-1)
nn = 4
case (6)
nn = 6
case (7,8:15,21:)
nn = 7
end select
sinteger = nn
end
! CHECK-LABEL: slogical
subroutine slogical(L)
logical :: L
n1 = 0
n2 = 0
n3 = 0
n4 = 0
n5 = 0
n6 = 0
n7 = 0
n8 = 0
select case (L)
end select
select case (L)
! CHECK: cmpi eq, {{.*}} %false
! CHECK: cond_br
case (.false.)
n2 = 1
end select
select case (L)
! CHECK: cmpi eq, {{.*}} %true
! CHECK: cond_br
case (.true.)
n3 = 2
end select
select case (L)
case default
n4 = 3
end select
select case (L)
! CHECK: cmpi eq, {{.*}} %false
! CHECK: cond_br
case (.false.)
n5 = 1
! CHECK: cmpi eq, {{.*}} %true
! CHECK: cond_br
case (.true.)
n5 = 2
end select
select case (L)
! CHECK: cmpi eq, {{.*}} %false
! CHECK: cond_br
case (.false.)
n6 = 1
case default
n6 = 3
end select
select case (L)
! CHECK: cmpi eq, {{.*}} %true
! CHECK: cond_br
case (.true.)
n7 = 2
case default
n7 = 3
end select
select case (L)
! CHECK: cmpi eq, {{.*}} %false
! CHECK: cond_br
case (.false.)
n8 = 1
! CHECK: cmpi eq, {{.*}} %true
! CHECK: cond_br
case (.true.)
n8 = 2
! CHECK-NOT: constant 888
case default ! dead
n8 = 888
end select
print*, n1, n2, n3, n4, n5, n6, n7, n8
end
! CHECK-LABEL: scharacter
subroutine scharacter(c)
character(*) :: c
nn = 0
select case (c)
case default
nn = -1
! CHECK: CharacterCompareScalar1
! CHECK-NEXT: constant 0
! CHECK-NEXT: cmpi sle, {{.*}} %c0
! CHECK-NEXT: cond_br
case (:'d')
nn = 10
! CHECK: CharacterCompareScalar1
! CHECK-NEXT: constant 0
! CHECK-NEXT: cmpi sge, {{.*}} %c0
! CHECK-NEXT: cond_br
! CHECK: CharacterCompareScalar1
! CHECK-NEXT: constant 0
! CHECK-NEXT: cmpi sle, {{.*}} %c0
! CHECK-NEXT: cond_br
case ('ff':'ffff')
nn = 20
! CHECK: CharacterCompareScalar1
! CHECK-NEXT: constant 0
! CHECK-NEXT: cmpi eq, {{.*}} %c0
! CHECK-NEXT: cond_br
case ('m')
nn = 30
! CHECK: CharacterCompareScalar1
! CHECK-NEXT: constant 0
! CHECK-NEXT: cmpi eq, {{.*}} %c0
! CHECK-NEXT: cond_br
case ('qq')
nn = 40
! CHECK: CharacterCompareScalar1
! CHECK-NEXT: constant 0
! CHECK-NEXT: cmpi sge, {{.*}} %c0
! CHECK-NEXT: cond_br
case ('x':)
nn = 50
end select
print*, nn
end
! CHECK-LABEL: func @_QPscharacter1
subroutine scharacter1(s)
! CHECK-DAG: %[[V_0:[0-9]+]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
character(len=3) :: s
! CHECK-DAG: %[[V_1:[0-9]+]] = fir.alloca i32 {bindc_name = "n", uniq_name = "_QFscharacter1En"}
! CHECK: fir.store %c0{{.*}} to %[[V_1]] : !fir.ref<i32>
n = 0
! CHECK: %[[V_8:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_9:[0-9]+]] = arith.cmpi sge, %[[V_8]], %c0{{.*}} : i32
! CHECK: cond_br %[[V_9]], ^bb1, ^bb15
! CHECK: ^bb1: // pred: ^bb0
if (lge(s,'00')) then
! CHECK: %[[V_18:[0-9]+]] = fir.load %[[V_0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[V_20:[0-9]+]] = fir.box_addr %[[V_18]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
! CHECK: %[[V_42:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_43:[0-9]+]] = arith.cmpi eq, %[[V_42]], %c0{{.*}} : i32
! CHECK: fir.if %[[V_43]] {
! CHECK: fir.freemem %[[V_20]] : !fir.heap<!fir.char<1,?>>
! CHECK: }
! CHECK: cond_br %[[V_43]], ^bb3, ^bb2
! CHECK: ^bb2: // pred: ^bb1
select case(trim(s))
case('11')
n = 1
case default
continue
! CHECK: %[[V_48:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_49:[0-9]+]] = arith.cmpi eq, %[[V_48]], %c0{{.*}} : i32
! CHECK: fir.if %[[V_49]] {
! CHECK: fir.freemem %[[V_20]] : !fir.heap<!fir.char<1,?>>
! CHECK: }
! CHECK: cond_br %[[V_49]], ^bb6, ^bb5
! CHECK: ^bb3: // pred: ^bb1
! CHECK: fir.store %c1{{.*}} to %[[V_1]] : !fir.ref<i32>
! CHECK: ^bb4: // pred: ^bb13
! CHECK: ^bb5: // pred: ^bb2
case('22')
n = 2
! CHECK: %[[V_54:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_55:[0-9]+]] = arith.cmpi eq, %[[V_54]], %c0{{.*}} : i32
! CHECK: fir.if %[[V_55]] {
! CHECK: fir.freemem %[[V_20]] : !fir.heap<!fir.char<1,?>>
! CHECK: }
! CHECK: cond_br %[[V_55]], ^bb8, ^bb7
! CHECK: ^bb6: // pred: ^bb2
! CHECK: fir.store %c2{{.*}} to %[[V_1]] : !fir.ref<i32>
! CHECK: ^bb7: // pred: ^bb5
case('33')
n = 3
case('44':'55','66':'77','88':)
n = 4
! CHECK: %[[V_60:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_61:[0-9]+]] = arith.cmpi sge, %[[V_60]], %c0{{.*}} : i32
! CHECK: cond_br %[[V_61]], ^bb9, ^bb10
! CHECK: ^bb8: // pred: ^bb5
! CHECK: fir.store %c3{{.*}} to %[[V_1]] : !fir.ref<i32>
! CHECK: ^bb9: // pred: ^bb7
! CHECK: %[[V_66:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_67:[0-9]+]] = arith.cmpi sle, %[[V_66]], %c0{{.*}} : i32
! CHECK: fir.if %[[V_67]] {
! CHECK: fir.freemem %[[V_20]] : !fir.heap<!fir.char<1,?>>
! CHECK: }
! CHECK: cond_br %[[V_67]], ^bb14, ^bb10
! CHECK: ^bb10: // 2 preds: ^bb7, ^bb9
! CHECK: %[[V_72:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_73:[0-9]+]] = arith.cmpi sge, %[[V_72]], %c0{{.*}} : i32
! CHECK: cond_br %[[V_73]], ^bb11, ^bb12
! CHECK: ^bb11: // pred: ^bb10
! CHECK: %[[V_78:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_79:[0-9]+]] = arith.cmpi sle, %[[V_78]], %c0{{.*}} : i32
! CHECK: fir.if %[[V_79]] {
! CHECK: fir.freemem %[[V_20]] : !fir.heap<!fir.char<1,?>>
! CHECK: }
! CHECK: ^bb12: // 2 preds: ^bb10, ^bb11
! CHECK: %[[V_84:[0-9]+]] = fir.call @_FortranACharacterCompareScalar1
! CHECK: %[[V_85:[0-9]+]] = arith.cmpi sge, %[[V_84]], %c0{{.*}} : i32
! CHECK: fir.freemem %[[V_20]] : !fir.heap<!fir.char<1,?>>
! CHECK: cond_br %[[V_85]], ^bb14, ^bb13
! CHECK: ^bb13: // pred: ^bb12
! CHECK: ^bb14: // 3 preds: ^bb9, ^bb11, ^bb12
! CHECK: fir.store %c4{{.*}} to %[[V_1]] : !fir.ref<i32>
! CHECK: ^bb15: // 6 preds: ^bb0, ^bb3, ^bb4, ^bb6, ^bb8, ^bb14
end select
end if
! CHECK: %[[V_89:[0-9]+]] = fir.load %[[V_1]] : !fir.ref<i32>
print*, n
end subroutine
! CHECK-LABEL: func @_QPscharacter2
subroutine scharacter2(s)
! CHECK-DAG: %[[V_0:[0-9]+]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
! CHECK: %[[V_1:[0-9]+]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
character(len=3) :: s
n = 0
! CHECK: %[[V_12:[0-9]+]] = fir.load %[[V_1]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[V_13:[0-9]+]] = fir.box_addr %[[V_12]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
! CHECK: fir.freemem %[[V_13]] : !fir.heap<!fir.char<1,?>>
! CHECK: br ^bb1
! CHECK: ^bb1: // pred: ^bb0
! CHECK: br ^bb2
n = -10
select case(trim(s))
case default
n = 9
end select
print*, n
! CHECK: ^bb2: // pred: ^bb1
! CHECK: %[[V_28:[0-9]+]] = fir.load %[[V_0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[V_29:[0-9]+]] = fir.box_addr %[[V_28]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
! CHECK: fir.freemem %[[V_29]] : !fir.heap<!fir.char<1,?>>
! CHECK: br ^bb3
! CHECK: ^bb3: // pred: ^bb2
n = -2
select case(trim(s))
end select
print*, n
end subroutine
! CHECK-LABEL: func @_QPswhere
subroutine swhere(num)
implicit none
integer, intent(in) :: num
real, dimension(1) :: array
array = 0.0
select case (num)
! CHECK: ^bb1: // pred: ^bb0
case (1)
where (array >= 0.0)
array = 42
end where
! CHECK: cf.br ^bb3
! CHECK: ^bb2: // pred: ^bb0
case default
array = -1
end select
! CHECK: cf.br ^bb3
! CHECK: ^bb3: // 2 preds: ^bb1, ^bb2
print*, array(1)
end subroutine swhere
! CHECK-LABEL: func @_QPsforall
subroutine sforall(num)
implicit none
integer, intent(in) :: num
real, dimension(1) :: array
array = 0.0
select case (num)
! CHECK: ^bb1: // pred: ^bb0
case (1)
where (array >= 0.0)
array = 42
end where
! CHECK: cf.br ^bb3
! CHECK: ^bb2: // pred: ^bb0
case default
array = -1
end select
! CHECK: cf.br ^bb3
! CHECK: ^bb3: // 2 preds: ^bb1, ^bb2
print*, array(1)
end subroutine sforall
! CHECK-LABEL: main
program p
integer sinteger, v(10)
n = -10
do j = 1, 4
do k = 1, 10
n = n + 1
v(k) = sinteger(n)
enddo
! expected output: 1 1 1 1 1 1 1 1 1 1
! 1 2 3 4 4 6 7 7 7 7
! 7 7 7 7 7 0 0 0 0 0
! 7 7 7 7 7 7 7 7 7 7
print*, v
enddo
print*
call slogical(.false.) ! expected output: 0 1 0 3 1 1 3 1
call slogical(.true.) ! expected output: 0 0 2 3 2 3 2 2
print*
call scharacter('aa') ! expected output: 10
call scharacter('d') ! expected output: 10
call scharacter('f') ! expected output: -1
call scharacter('ff') ! expected output: 20
call scharacter('fff') ! expected output: 20
call scharacter('ffff') ! expected output: 20
call scharacter('fffff') ! expected output: -1
call scharacter('jj') ! expected output: -1
call scharacter('m') ! expected output: 30
call scharacter('q') ! expected output: -1
call scharacter('qq') ! expected output: 40
call scharacter('qqq') ! expected output: -1
call scharacter('vv') ! expected output: -1
call scharacter('xx') ! expected output: 50
call scharacter('zz') ! expected output: 50
print*
call scharacter1('99 ') ! expected output: 4
call scharacter1('88 ') ! expected output: 4
call scharacter1('77 ') ! expected output: 4
call scharacter1('66 ') ! expected output: 4
call scharacter1('55 ') ! expected output: 4
call scharacter1('44 ') ! expected output: 4
call scharacter1('33 ') ! expected output: 3
call scharacter1('22 ') ! expected output: 2
call scharacter1('11 ') ! expected output: 1
call scharacter1('00 ') ! expected output: 0
call scharacter1('. ') ! expected output: 0
call scharacter1(' ') ! expected output: 0
print*
call scharacter2('99 ') ! expected output: 9 -2
call scharacter2('22 ') ! expected output: 9 -2
call scharacter2('. ') ! expected output: 9 -2
call scharacter2(' ') ! expected output: 9 -2
print*
call swhere(1) ! expected output: 42.
call sforall(1) ! expected output: 42.
end