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