1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
! Test forall scheduling analysis from lower-hlfir-ordered-assignments pass.
! The printed output is done via LLVM_DEBUG, hence the "asserts" requirement.
! This test test that conflicting actions are not scheduled to be evaluated
! in the same loops (same run id).
! RUN: bbc -hlfir -o - -pass-pipeline="builtin.module(lower-hlfir-ordered-assignments)" --debug-only=flang-ordered-assignment -flang-dbg-order-assignment-schedule-only %s 2>&1 | FileCheck %s
! REQUIRES: asserts
subroutine no_conflict(x)
real :: x(:)
forall(i=1:10) x(i) = i
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPno_conflict ------------
!CHECK-NEXT: run 1 evaluate: forall/region_assign1
subroutine rhs_lhs_overlap(x)
real :: x(:)
forall(i=1:10) x(i) = x(11-i)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPrhs_lhs_overlap ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?xf32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?xf32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/region_assign1/rhs
!CHECK-NEXT: run 2 evaluate: forall/region_assign1
subroutine no_rhs_lhs_overlap(x, y)
real :: x(:), y(:)
forall(i=1:10) x(i) = y(i)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPno_rhs_lhs_overlap ------------
!CHECK-NEXT: run 1 evaluate: forall/region_assign1
subroutine no_rhs_lhs_overlap_2(x)
real :: x(:), y(10)
forall(i=1:10) x(i) = y(i)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPno_rhs_lhs_overlap_2 ------------
!CHECK-NEXT: run 1 evaluate: forall/region_assign1
subroutine no_rhs_lhs_overlap_3()
real :: x(10), y(10)
forall(i=1:10) x(i) = y(i)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPno_rhs_lhs_overlap_3 ------------
!CHECK-NEXT: run 1 evaluate: forall/region_assign1
subroutine array_expr_rhs_lhs_overlap(x)
real :: x(:, :)
forall(i=1:10) x(i, :) = x(:, i)*2
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QParray_expr_rhs_lhs_overlap ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/region_assign1/rhs
!CHECK-NEXT: run 2 evaluate: forall/region_assign1
subroutine array_expr_no_rhs_lhs_overlap(x, y, z)
real :: x(:, :), y(:, :), z(:, :)
forall(i=1:10) x(i, :) = y(:, i) + z(i, :)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QParray_expr_no_rhs_lhs_overlap ------------
!CHECK-NEXT: run 1 evaluate: forall/region_assign1
subroutine rhs_lhs_overlap_2(x, y)
real, target :: x(:), y(:)
forall(i=1:10) x(i) = y(i)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPrhs_lhs_overlap_2 ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?xf32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?xf32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/region_assign1/rhs
!CHECK-NEXT: run 2 evaluate: forall/region_assign1
subroutine lhs_lhs_overlap(x)
integer :: x(10)
forall(i=1:10) x(x(i)) = i
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPlhs_lhs_overlap ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.ref<!fir.array<10xi32>>' at index: 0 W:<block argument> of type '!fir.ref<!fir.array<10xi32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/region_assign1/lhs
!CHECK-NEXT: run 2 evaluate: forall/region_assign1
subroutine unknown_function_call(x)
interface
pure real function foo(x, i)
integer, intent(in) :: i
real, intent(in) :: x(10)
end function
end interface
real :: x(10)
forall(i=1:10) x(i) = foo(x, i)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPunknown_function_call ------------
!CHECK-NEXT: unknown effect: {{.*}} fir.call @_QPfoo
!CHECK-NEXT: conflict: R/W: <unknown> W:<block argument> of type '!fir.ref<!fir.array<10xf32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/region_assign1/rhs
!CHECK-NEXT: run 2 evaluate: forall/region_assign1
subroutine unknown_function_call2(x)
interface
pure real function foo2(i)
integer, value :: i
end function
end interface
! foo2 may read x since it is a target, even if it is pure,
! if the actual argument of x is a module variable accessible
! to foo via host association.
real, target :: x(:)
forall(i=1:10) x(i) = foo2(i)
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPunknown_function_call2 ------------
!CHECK-NEXT: unknown effect: {{.*}} fir.call @_QPfoo2(
!CHECK-NEXT: conflict: R/W: <unknown> W:<block argument> of type '!fir.box<!fir.array<?xf32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/region_assign1/rhs
!CHECK-NEXT: run 2 evaluate: forall/region_assign1
subroutine forall_mask_conflict(x)
integer :: x(:)
forall(i=1:10, x(11-i)>0) x(i) = 42
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPforall_mask_conflict ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?xi32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?xi32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/forall_mask1/mask
!CHECK-NEXT: run 2 evaluate: forall/forall_mask1/region_assign1
subroutine forall_ub_conflict(x, y)
integer :: x(:, :)
forall(i=1:10)
forall(j=1:x(i,i))
x(i, j) = 42
end forall
end forall
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPforall_ub_conflict ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/forall1/ub
!CHECK-NEXT: run 2 evaluate: forall/forall1/region_assign1
subroutine sequential_assign(x, y)
integer :: x(:), y(:)
forall(i=1:10)
x(i) = y(i)
y(2*i) = x(i)
end forall
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPsequential_assign ------------
!CHECK-NEXT: run 1 evaluate: forall/region_assign1
!CHECK-NEXT: run 2 evaluate: forall/region_assign2
subroutine loads_of_conlficts(x, y)
integer, target :: x(:, :), y(:, :)
forall(i=1:10)
forall (j=1:y(i,i)) x(x(i, j), j) = y(i, j)
forall (j=1:x(i,i), y(i,i)>0) y(x(i, j), j) = 0
end forall
end subroutine
!CHECK-LABEL: ------------ scheduling forall in _QPloads_of_conlficts ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/forall1/ub
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/forall1/region_assign1/rhs
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0
!CHECK-NEXT: run 1 save : forall/forall1/region_assign1/lhs
!CHECK-NEXT: run 2 evaluate: forall/forall1/region_assign1
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 1
!CHECK-NEXT: run 3 save : forall/forall2/ub
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 1
!CHECK-NEXT: run 3 save : forall/forall2/forall_mask1/mask
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xi32>>' at index: 1
!CHECK-NEXT: run 3 save : forall/forall2/forall_mask1/region_assign1/lhs
!CHECK-NEXT: run 4 evaluate: forall/forall2/forall_mask1/region_assign1
|