
The new LLVM stack save/restore intrinsic operations are more convenient than function calls because they do not add function declarations to the module and therefore do not block the parallelisation of passes. Furthermore they could be much more easily marked with memory effects than function calls if that ever proved useful. This builds on top of #107879. Resolves #108016
99 lines
3.8 KiB
Fortran
99 lines
3.8 KiB
Fortran
! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s
|
|
|
|
! CHECK-LABEL: func @_QQmain
|
|
program bb ! block stack management and exits
|
|
! CHECK: %[[V_0:[0-9]+]] = fir.alloca i32 {adapt.valuebyref}
|
|
! CHECK: %[[V_1:[0-9]+]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
|
|
integer :: i, j
|
|
! CHECK: fir.store %c0{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
i = 0
|
|
! CHECK: %[[V_3:[0-9]+]] = llvm.intr.stacksave : !llvm.ptr
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: br ^bb1
|
|
! CHECK: ^bb1: // 2 preds: ^bb0, ^bb16
|
|
! CHECK: cond_br %{{.*}}, ^bb2, ^bb17
|
|
! CHECK: ^bb2: // pred: ^bb1
|
|
! CHECK: %[[V_11:[0-9]+]] = llvm.intr.stacksave : !llvm.ptr
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: cond_br %{{.*}}, ^bb3, ^bb4
|
|
! CHECK: ^bb3: // pred: ^bb2
|
|
! CHECK: br ^bb10
|
|
! CHECK: ^bb4: // pred: ^bb2
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: cond_br %{{.*}}, ^bb5, ^bb6
|
|
! CHECK: ^bb5: // pred: ^bb4
|
|
! CHECK: br ^bb14
|
|
! CHECK: ^bb6: // pred: ^bb4
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: cond_br %{{.*}}, ^bb7, ^bb8
|
|
! CHECK: ^bb7: // pred: ^bb6
|
|
! CHECK: llvm.intr.stackrestore %[[V_11]] : !llvm.ptr
|
|
! CHECK: br ^bb15
|
|
! CHECK: ^bb8: // pred: ^bb6
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: cond_br %{{.*}}, ^bb9, ^bb10
|
|
! CHECK: ^bb9: // pred: ^bb8
|
|
! CHECK: llvm.intr.stackrestore %[[V_11]] : !llvm.ptr
|
|
! CHECK: br ^bb16
|
|
! CHECK: ^bb10: // 2 preds: ^bb3, ^bb8
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: cond_br %{{.*}}, ^bb11, ^bb12
|
|
! CHECK: ^bb11: // pred: ^bb10
|
|
! CHECK: llvm.intr.stackrestore %[[V_11]] : !llvm.ptr
|
|
! CHECK: br ^bb18
|
|
! CHECK: ^bb12: // pred: ^bb10
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: cond_br %{{.*}}, ^bb13, ^bb14
|
|
! CHECK: ^bb13: // pred: ^bb12
|
|
! CHECK: llvm.intr.stackrestore %[[V_11]] : !llvm.ptr
|
|
! CHECK: llvm.intr.stackrestore %[[V_3]] : !llvm.ptr
|
|
! CHECK: br ^bb19
|
|
! CHECK: ^bb14: // 2 preds: ^bb5, ^bb12
|
|
! CHECK: llvm.intr.stackrestore %[[V_11]] : !llvm.ptr
|
|
! CHECK: br ^bb15
|
|
! CHECK: ^bb15: // 2 preds: ^bb7, ^bb14
|
|
! CHECK: br ^bb16
|
|
! CHECK: ^bb16: // 2 preds: ^bb9, ^bb15
|
|
! CHECK: br ^bb1
|
|
! CHECK: ^bb17: // pred: ^bb1
|
|
! CHECK: fir.store %{{.*}} to %[[V_1]] : !fir.ref<i32>
|
|
! CHECK: cf.br ^bb18
|
|
! CHECK: ^bb18: // 2 preds: ^bb11, ^bb17
|
|
! CHECK: llvm.intr.stackrestore %[[V_3]] : !llvm.ptr
|
|
! CHECK: br ^bb19
|
|
! CHECK: ^bb19: // 2 preds: ^bb13, ^bb18
|
|
block
|
|
i = i + 1 ! 1 increment
|
|
do j = 1, 5
|
|
block
|
|
i = i + 1; if (j == 1) goto 1 ! inner block - 5 increments, 1 goto
|
|
i = i + 1; if (j == 2) goto 2 ! inner block - 4 increments, 1 goto
|
|
i = i + 1; if (j == 3) goto 10 ! outer block - 3 increments, 1 goto
|
|
i = i + 1; if (j == 4) goto 11 ! outer block - 2 increments, 1 goto
|
|
1 i = i + 1; if (j == 5) goto 12 ! outer block - 2 increments, 1 goto
|
|
i = i + 1; if (j == 6) goto 100 ! program - 1 increment
|
|
2 end block
|
|
10 i = i + 1 ! 3 increments
|
|
11 end do
|
|
i = i + 1 ! 0 increments
|
|
12 end block
|
|
100 print*, i ! expect 21
|
|
|
|
! CHECK: %[[V_51:[0-9]+]] = llvm.intr.stacksave : !llvm.ptr
|
|
! CHECK: fir.store %c5{{.*}} to %[[V_0]] : !fir.ref<i32>
|
|
! CHECK: fir.call @ss(%[[V_0]]) proc_attrs<bind_c> fastmath<contract> : (!fir.ref<i32>) -> ()
|
|
! CHECK: llvm.intr.stackrestore %[[V_51]] : !llvm.ptr
|
|
block
|
|
interface
|
|
subroutine ss(n) bind(c)
|
|
integer :: n
|
|
end subroutine
|
|
end interface
|
|
call ss(5)
|
|
end block
|
|
end
|
|
|
|
subroutine ss(n) bind(c)
|
|
print*, n
|
|
end subroutine
|