xref: /llvm-project/flang/test/HLFIR/order_assignments/where-scheduling.f90 (revision cd7e65398fbbd9642573013800dc3ae1e7307f82)
1222a8a1bSJean Perier! Test scheduling of WHERE in lower-hlfir-ordered-assignments pass.
2222a8a1bSJean Perier
3222a8a1bSJean Perier! 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
4222a8a1bSJean Perier! REQUIRES: asserts
5222a8a1bSJean Perier
6222a8a1bSJean Periersubroutine no_conflict(x, y)
7222a8a1bSJean Perier  real :: x(:), y(:)
8222a8a1bSJean Perier  where (y.gt.0) x = y
9222a8a1bSJean Perierend subroutine
10222a8a1bSJean Perier
11222a8a1bSJean Periersubroutine fake_conflict(x, y)
12222a8a1bSJean Perier  ! The conflict here could be avoided because the read and write are
13222a8a1bSJean Perier  ! aligned, so there would not be any read after write at the element
14222a8a1bSJean Perier  ! level, but this will require a bit more work to detect this (like
15222a8a1bSJean Perier  ! comparing the hlfir.designate operations).
16222a8a1bSJean Perier  real :: x(:), y(:)
17222a8a1bSJean Perier  where (x.gt.y) x = y
18222a8a1bSJean Perierend subroutine
19222a8a1bSJean Perier
20222a8a1bSJean Periersubroutine only_once(x, y, z)
21222a8a1bSJean Perier  interface
22222a8a1bSJean Perier    impure function call_me_only_once()
23222a8a1bSJean Perier      logical :: call_me_only_once(10)
24222a8a1bSJean Perier    end function
25222a8a1bSJean Perier  end interface
26222a8a1bSJean Perier  real :: x(:), y(:), z(:)
27222a8a1bSJean Perier  where (call_me_only_once())
28222a8a1bSJean Perier    x = y
29222a8a1bSJean Perier    z = y
30222a8a1bSJean Perier  end where
31222a8a1bSJean Perierend subroutine
32222a8a1bSJean Perier
33222a8a1bSJean Periersubroutine rhs_lhs_conflict(x, y)
34222a8a1bSJean Perier  real :: x(:, :), y(:, :)
35222a8a1bSJean Perier  where (y.gt.0.) x = transpose(x)
36222a8a1bSJean Perierend subroutine
37222a8a1bSJean Perier
38222a8a1bSJean Periersubroutine where_construct_no_conflict(x, y, z, mask1, mask2)
39222a8a1bSJean Perier  real :: x(:), y(:), z(:)
40222a8a1bSJean Perier  logical :: mask1(:), mask2(:)
41222a8a1bSJean Perier  where (mask1)
42222a8a1bSJean Perier    x = y
43222a8a1bSJean Perier  elsewhere (mask2)
44222a8a1bSJean Perier    z = y
45222a8a1bSJean Perier  end where
46222a8a1bSJean Perierend subroutine
47222a8a1bSJean Perier
48222a8a1bSJean Periersubroutine where_construct_conflict(x, y)
49222a8a1bSJean Perier  real :: x(:, :), y(:, :)
50222a8a1bSJean Perier  where (y.gt.0.)
51222a8a1bSJean Perier    x = y
52222a8a1bSJean Perier  elsewhere (x.gt.0)
53222a8a1bSJean Perier    y = x
54222a8a1bSJean Perier  end where
55222a8a1bSJean Perierend subroutine
56222a8a1bSJean Perier
57222a8a1bSJean Periersubroutine where_construct_conflict_2(x, y)
58222a8a1bSJean Perier  real :: x(:, :), y(:, :)
59222a8a1bSJean Perier  where (x.gt.0.)
60222a8a1bSJean Perier    x = y
61222a8a1bSJean Perier  elsewhere (y.gt.0)
62222a8a1bSJean Perier    y = x
63222a8a1bSJean Perier  end where
64222a8a1bSJean Perierend subroutine
65222a8a1bSJean Perier
66222a8a1bSJean Periersubroutine where_vector_subscript_conflict_1(x, vec1)
67222a8a1bSJean Perier  real :: x(10)
68222a8a1bSJean Perier  integer :: vec1(10)
69222a8a1bSJean Perier  where (x(vec1).lt.0.) x = 42.
70222a8a1bSJean Perierend subroutine
71222a8a1bSJean Perier
72222a8a1bSJean Periersubroutine where_vector_subscript_conflict_2(x, vec1)
73222a8a1bSJean Perier  integer :: x(10)
74222a8a1bSJean Perier  real :: y(10)
75222a8a1bSJean Perier  where (y(x).lt.0.) x = 0
76222a8a1bSJean Perierend subroutine
77222a8a1bSJean Perier
78222a8a1bSJean Periersubroutine where_in_forall_conflict(x)
79222a8a1bSJean Perier  real :: x(:, :)
80222a8a1bSJean Perier  forall (i = 1:10)
81222a8a1bSJean Perier    where (x(i, :).gt.0) x(:, i) = x(i, :)
82222a8a1bSJean Perier  end forall
83222a8a1bSJean Perierend subroutine
84222a8a1bSJean Perier
85e52a6d77SJean Periersubroutine no_need_to_make_lhs_temp(x, y, i, j)
86e52a6d77SJean Perier  integer :: j, i, x(:, :), y(:, :)
87e52a6d77SJean Perier  call internal
88e52a6d77SJean Periercontains
89e52a6d77SJean Periersubroutine internal
90e52a6d77SJean Perier  ! The internal procedure context currently gives a hard time to
91e52a6d77SJean Perier  ! FIR alias analysis that flags the read of i,j and y as conflicting
92e52a6d77SJean Perier  ! with the write to x. But this is not a reason to create a temporary
93e52a6d77SJean Perier  ! storage for the LHS: the address is anyway fully computed in
94e52a6d77SJean Perier  ! a descriptor (fir.box) before assigning any element of x.
95e52a6d77SJean Perier
96e52a6d77SJean Perier  ! Note that the where mask is also saved while there is no real
97e52a6d77SJean Perier  ! need to: it is addressing x elements in the same order as they
98e52a6d77SJean Perier  ! are being assigned. But this will require more work in the
99e52a6d77SJean Perier  ! conflict analysis to prove that the lowered DAG of `x(:, y(i, j))`
100e52a6d77SJean Perier  ! are the same and that the access to this designator is done in the
101e52a6d77SJean Perier  ! same ordered inside the mask and LHS.
102e52a6d77SJean Perier  where (x(:, y(i, j)) == y(i, j))  x(:, y(i, j)) = 42
103e52a6d77SJean Perierend subroutine
104e52a6d77SJean Perierend subroutine
105e52a6d77SJean Perier
1067095a86fSSlava Zakharinsubroutine where_construct_unknown_conflict(x, mask)
1077095a86fSSlava Zakharin  real :: x(:)
1087095a86fSSlava Zakharin  logical :: mask(:)
1097095a86fSSlava Zakharin  interface
1107095a86fSSlava Zakharin     real function f()
1117095a86fSSlava Zakharin     end function f
1127095a86fSSlava Zakharin  end interface
1137095a86fSSlava Zakharin  where (mask) x = f()
1147095a86fSSlava Zakharinend subroutine
1157095a86fSSlava Zakharin
1167095a86fSSlava Zakharinsubroutine elsewhere_construct_unknown_conflict(x, y, mask1, mask2)
1177095a86fSSlava Zakharin  real :: x(:), y(:)
1187095a86fSSlava Zakharin  logical :: mask1(:), mask2(:)
1197095a86fSSlava Zakharin  interface
1207095a86fSSlava Zakharin     real function f()
1217095a86fSSlava Zakharin     end function f
1227095a86fSSlava Zakharin  end interface
1237095a86fSSlava Zakharin  where (mask1)
1247095a86fSSlava Zakharin     x = 1.0
1257095a86fSSlava Zakharin  elsewhere (mask2)
1267095a86fSSlava Zakharin     y = f()
1277095a86fSSlava Zakharin  end where
1287095a86fSSlava Zakharinend subroutine
1297095a86fSSlava Zakharin
130222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPno_conflict ------------
131222a8a1bSJean Perier!CHECK-NEXT: run 1 evaluate: where/region_assign1
132222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPfake_conflict ------------
133222a8a1bSJean Perier!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
134222a8a1bSJean Perier!CHECK-NEXT: run 1 save    : where/mask
135222a8a1bSJean Perier!CHECK-NEXT: run 2 evaluate: where/region_assign1
136222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPonly_once ------------
137*cd7e6539SjeanPerier!CHECK-NEXT: unknown effect: %11 = fir.call @_QPcall_me_only_once() fastmath<contract> : () -> !fir.array<10x!fir.logical<4>>
138a59f7124SjeanPerier!CHECK-NEXT: saving eval because write effect prevents re-evaluation
139222a8a1bSJean Perier!CHECK-NEXT: run 1 save  (w): where/mask
140222a8a1bSJean Perier!CHECK-NEXT: run 2 evaluate: where/region_assign1
141222a8a1bSJean Perier!CHECK-NEXT: run 3 evaluate: where/region_assign2
142222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPrhs_lhs_conflict ------------
14343d729ddSTom Eccles!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
14443d729ddSTom Eccles!CHECK-NEXT: run 1 save    : where/region_assign1/rhs
14543d729ddSTom Eccles!CHECK-NEXT: run 2 evaluate: where/region_assign1
146222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPwhere_construct_no_conflict ------------
147222a8a1bSJean Perier!CHECK-NEXT: run 1 evaluate: where/region_assign1
148222a8a1bSJean Perier!CHECK-NEXT: run 2 evaluate: where/elsewhere1/region_assign1
149222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPwhere_construct_conflict ------------
150222a8a1bSJean Perier!CHECK-NEXT: run 1 evaluate: where/region_assign1
151222a8a1bSJean Perier!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1
152222a8a1bSJean Perier!CHECK-NEXT: run 2 save    : where/mask
153222a8a1bSJean Perier!CHECK-NEXT: run 3 evaluate: where/elsewhere1/region_assign1
154222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPwhere_construct_conflict_2 ------------
155222a8a1bSJean Perier!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
156222a8a1bSJean Perier!CHECK-NEXT: run 1 save    : where/mask
157222a8a1bSJean Perier!CHECK-NEXT: run 2 evaluate: where/region_assign1
158222a8a1bSJean Perier!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1
159222a8a1bSJean Perier!CHECK-NEXT: run 3 save    : where/elsewhere1/mask
160222a8a1bSJean Perier!CHECK-NEXT: run 4 evaluate: where/elsewhere1/region_assign1
161222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPwhere_vector_subscript_conflict_1 ------------
162222a8a1bSJean Perier!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.ref<!fir.array<10xf32>>' at index: 0 W:<block argument> of type '!fir.ref<!fir.array<10xf32>>' at index: 0
163222a8a1bSJean Perier!CHECK-NEXT: run 1 save    : where/mask
164222a8a1bSJean Perier!CHECK-NEXT: run 2 evaluate: where/region_assign1
165222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling where in _QPwhere_vector_subscript_conflict_2 ------------
166222a8a1bSJean Perier!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
167222a8a1bSJean Perier!CHECK-NEXT: run 1 save    : where/mask
168222a8a1bSJean Perier!CHECK-NEXT: run 2 evaluate: where/region_assign1
169222a8a1bSJean Perier!CHECK-LABEL: ------------ scheduling forall in _QPwhere_in_forall_conflict ------------
170222a8a1bSJean Perier!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
171222a8a1bSJean Perier!CHECK-NEXT: run 1 save    : forall/where1/mask
172222a8a1bSJean Perier!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
173222a8a1bSJean Perier!CHECK-NEXT: run 1 save    : forall/where1/region_assign1/rhs
174222a8a1bSJean Perier!CHECK-NEXT: run 2 evaluate: forall/where1/region_assign1
175e52a6d77SJean Perier!CHECK-LABEL: ------------ scheduling where in _QFno_need_to_make_lhs_tempPinternal ------------
1761710c8cfSSlava Zakharin!CHECK-NEXT: conflict: R/W: %{{[0-9]+}} = fir.load %{{[0-9]+}} : !fir.llvm_ptr<!fir.ref<i32>> W:%{{[0-9]+}} = fir.load %{{[0-9]+}} : !fir.ref<!fir.box<!fir.array<?x?xi32>>>
177e52a6d77SJean Perier!CHECK-NEXT: run 1 save    : where/mask
178e52a6d77SJean Perier!CHECK-NEXT: run 2 evaluate: where/region_assign1
1797095a86fSSlava Zakharin!CHECK-NEXT: ------------ scheduling where in _QPwhere_construct_unknown_conflict ------------
1807095a86fSSlava Zakharin!CHECK-NEXT: unknown effect: %{{.*}} = fir.call @_QPf() fastmath<contract> : () -> f32
1811710c8cfSSlava Zakharin!CHECK-NEXT: conflict: R/W: %{{.*}} = hlfir.declare %{{.*}} {uniq_name = "_QFwhere_construct_unknown_conflictEmask"} : (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.box<!fir.array<?x!fir.logical<4>>>) W:<unknown>
1827095a86fSSlava Zakharin!CHECK-NEXT: run 1 save    : where/mask
1837095a86fSSlava Zakharin!CHECK-NEXT: unknown effect: %{{.*}} = fir.call @_QPf() fastmath<contract> : () -> f32
184a59f7124SjeanPerier!CHECK-NEXT: saving eval because write effect prevents re-evaluation
1857095a86fSSlava Zakharin!CHECK-NEXT: run 2 save  (w): where/region_assign1/rhs
1867095a86fSSlava Zakharin!CHECK-NEXT: run 3 evaluate: where/region_assign1
1877095a86fSSlava Zakharin!CHECK-NEXT: ------------ scheduling where in _QPelsewhere_construct_unknown_conflict ------------
1887095a86fSSlava Zakharin!CHECK-NEXT: run 1 evaluate: where/region_assign1
1897095a86fSSlava Zakharin!CHECK-NEXT: unknown effect: %{{.*}} = fir.call @_QPf() fastmath<contract> : () -> f32
1901710c8cfSSlava Zakharin!CHECK-NEXT: conflict: R/W: %{{.*}} = hlfir.declare %{{.*}} {uniq_name = "_QFelsewhere_construct_unknown_conflictEmask1"} : (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.box<!fir.array<?x!fir.logical<4>>>) W:<unknown>
1917095a86fSSlava Zakharin!CHECK-NEXT: run 2 save    : where/mask
1921710c8cfSSlava Zakharin!CHECK-NEXT: conflict: R/W: %{{.*}} = hlfir.declare %{{.*}} {uniq_name = "_QFelsewhere_construct_unknown_conflictEmask2"} : (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.box<!fir.array<?x!fir.logical<4>>>) W:<unknown>
1937095a86fSSlava Zakharin!CHECK-NEXT: run 2 save    : where/elsewhere1/mask
1947095a86fSSlava Zakharin!CHECK-NEXT: unknown effect: %{{.*}} = fir.call @_QPf() fastmath<contract> : () -> f32
195a59f7124SjeanPerier!CHECK-NEXT: saving eval because write effect prevents re-evaluation
1967095a86fSSlava Zakharin!CHECK-NEXT: run 3 save  (w): where/elsewhere1/region_assign1/rhs
1977095a86fSSlava Zakharin!CHECK-NEXT: run 4 evaluate: where/elsewhere1/region_assign1
198