| ! Test lowering of non elemental calls and there inputs inside WHERE |
| ! constructs. These must be lowered inside hlfir.exactly_once so that |
| ! they are properly hoisted once the loops are materialized and |
| ! expression evaluations are scheduled. |
| ! RUN: bbc -emit-hlfir -o - %s | FileCheck %s |
| |
| subroutine test_where(a, b, c) |
| real, dimension(:) :: a, b, c |
| interface |
| function logical_func1() |
| logical :: logical_func1(100) |
| end function |
| function logical_func2() |
| logical :: logical_func2(100) |
| end function |
| real elemental function elem_func(x) |
| real, intent(in) :: x |
| end function |
| end interface |
| where (logical_func1()) |
| a = b + real_func(a+b+real_func2()) + elem_func(a) |
| elsewhere(logical_func2()) |
| a(1:ifoo()) = c |
| end where |
| end subroutine |
| ! CHECK-LABEL: func.func @_QPtest_where( |
| ! CHECK: hlfir.where { |
| ! CHECK-NOT: hlfir.exactly_once |
| ! CHECK: %[[VAL_17:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> |
| ! CHECK: %[[VAL_19:.*]] = fir.call @_QPlogical_func1() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> |
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { |
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_17]]) fastmath<contract> : (!fir.ref<i8>) -> () |
| ! CHECK: } |
| ! CHECK: } do { |
| ! CHECK: hlfir.region_assign { |
| ! CHECK: %[[VAL_24:.*]] = hlfir.exactly_once : f32 { |
| ! CHECK: %[[VAL_28:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: } |
| ! CHECK-NOT: hlfir.exactly_once |
| ! CHECK: %[[VAL_35:.*]] = fir.call @_QPreal_func2() fastmath<contract> : () -> f32 |
| ! CHECK: %[[VAL_36:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: ^bb0(%[[VAL_37:.*]]: index): |
| ! CHECK: %[[VAL_38:.*]] = hlfir.apply %[[VAL_28]], %[[VAL_37]] : (!hlfir.expr<?xf32>, index) -> f32 |
| ! CHECK: %[[VAL_39:.*]] = arith.addf %[[VAL_38]], %[[VAL_35]] fastmath<contract> : f32 |
| ! CHECK: hlfir.yield_element %[[VAL_39]] : f32 |
| ! CHECK: } |
| ! CHECK: %[[VAL_41:.*]] = fir.call @_QPreal_func |
| ! CHECK: hlfir.yield %[[VAL_41]] : f32 cleanup { |
| ! CHECK: hlfir.destroy %[[VAL_36]] : !hlfir.expr<?xf32> |
| ! CHECK: hlfir.destroy %[[VAL_28]] : !hlfir.expr<?xf32> |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: %[[VAL_45:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: arith.addf |
| ! CHECK-NOT: hlfir.exactly_once |
| ! CHECK: } |
| ! CHECK: %[[VAL_53:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: fir.call @_QPelem_func |
| ! CHECK: } |
| ! CHECK: %[[VAL_57:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: arith.addf |
| ! CHECK: } |
| ! CHECK: hlfir.yield %[[VAL_57]] : !hlfir.expr<?xf32> cleanup { |
| ! CHECK: hlfir.destroy %[[VAL_57]] : !hlfir.expr<?xf32> |
| ! CHECK: hlfir.destroy %[[VAL_53]] : !hlfir.expr<?xf32> |
| ! CHECK: hlfir.destroy %[[VAL_45]] : !hlfir.expr<?xf32> |
| ! CHECK: } |
| ! CHECK: } to { |
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> |
| ! CHECK: } |
| ! CHECK: hlfir.elsewhere mask { |
| ! CHECK: %[[VAL_62:.*]] = hlfir.exactly_once : !hlfir.expr<100x!fir.logical<4>> { |
| ! CHECK: %[[VAL_72:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> |
| ! CHECK: fir.call @_QPlogical_func2() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> |
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { |
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_72]]) fastmath<contract> : (!fir.ref<i8>) -> () |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: hlfir.yield %[[VAL_62]] : !hlfir.expr<100x!fir.logical<4>> |
| ! CHECK: } do { |
| ! CHECK: hlfir.region_assign { |
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> |
| ! CHECK: } to { |
| ! CHECK: %[[VAL_80:.*]] = hlfir.exactly_once : i32 { |
| ! CHECK: %[[VAL_81:.*]] = fir.call @_QPifoo() fastmath<contract> : () -> i32 |
| ! CHECK: hlfir.yield %[[VAL_81]] : i32 |
| ! CHECK: } |
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: return |
| ! CHECK: } |
| |
| subroutine test_where_in_forall(a, b, c) |
| real, dimension(:, :) :: a, b, c |
| interface |
| pure function pure_logical_func1() |
| logical :: pure_logical_func1(100) |
| end function |
| pure function pure_logical_func2() |
| logical :: pure_logical_func2(100) |
| end function |
| real pure elemental function pure_elem_func(x) |
| real, intent(in) :: x |
| end function |
| integer pure function pure_ifoo() |
| end function |
| end interface |
| forall(i=1:10) |
| where (pure_logical_func1()) |
| a(2*i, :) = b(i, :) + pure_real_func(a(i,:)+b(i,:)+pure_real_func2()) + pure_elem_func(a(i,:)) |
| elsewhere(pure_logical_func2()) |
| a(2*i, 1:pure_ifoo()) = c(i, :) |
| end where |
| end forall |
| end subroutine |
| ! CHECK-LABEL: func.func @_QPtest_where_in_forall( |
| ! CHECK: hlfir.forall lb { |
| ! CHECK: hlfir.yield %{{.*}} : i32 |
| ! CHECK: } ub { |
| ! CHECK: hlfir.yield %{{.*}} : i32 |
| ! CHECK: } (%[[VAL_10:.*]]: i32) { |
| ! CHECK: %[[VAL_11:.*]] = hlfir.forall_index "i" %[[VAL_10]] : (i32) -> !fir.ref<i32> |
| ! CHECK: hlfir.where { |
| ! CHECK: %[[VAL_21:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> |
| ! CHECK-NOT: hlfir.exactly_once |
| ! CHECK: %[[VAL_23:.*]] = fir.call @_QPpure_logical_func1() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> |
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { |
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_21]]) fastmath<contract> : (!fir.ref<i8>) -> () |
| ! CHECK: } |
| ! CHECK: } do { |
| ! CHECK: hlfir.region_assign { |
| ! CHECK: %[[VAL_41:.*]] = hlfir.designate |
| ! CHECK: %[[VAL_42:.*]] = hlfir.exactly_once : f32 { |
| ! CHECK: hlfir.designate |
| ! CHECK: hlfir.designate |
| ! CHECK: %[[VAL_71:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: arith.addf |
| ! CHECK: } |
| ! CHECK-NOT: hlfir.exactly_once |
| ! CHECK: %[[VAL_78:.*]] = fir.call @_QPpure_real_func2() fastmath<contract> : () -> f32 |
| ! CHECK: %[[VAL_79:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: arith.addf |
| ! CHECK: } |
| ! CHECK: %[[VAL_84:.*]] = fir.call @_QPpure_real_func( |
| ! CHECK: hlfir.yield %[[VAL_84]] : f32 cleanup { |
| ! CHECK: hlfir.destroy %[[VAL_79]] : !hlfir.expr<?xf32> |
| ! CHECK: hlfir.destroy %[[VAL_71]] : !hlfir.expr<?xf32> |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: %[[VAL_85:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: arith.addf |
| ! CHECK: } |
| ! CHECK-NOT: hlfir.exactly_once |
| ! CHECK: %[[VAL_104:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: ^bb0(%[[VAL_105:.*]]: index): |
| ! CHECK-NOT: hlfir.exactly_once |
| ! CHECK: fir.call @_QPpure_elem_func |
| ! CHECK: } |
| ! CHECK: %[[VAL_108:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> { |
| ! CHECK: arith.addf |
| ! CHECK: } |
| ! CHECK: hlfir.yield %[[VAL_108]] : !hlfir.expr<?xf32> cleanup { |
| ! CHECK: hlfir.destroy %[[VAL_108]] : !hlfir.expr<?xf32> |
| ! CHECK: hlfir.destroy %[[VAL_104]] : !hlfir.expr<?xf32> |
| ! CHECK: hlfir.destroy %[[VAL_85]] : !hlfir.expr<?xf32> |
| ! CHECK: } |
| ! CHECK: } to { |
| ! CHECK: hlfir.designate |
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> |
| ! CHECK: } |
| ! CHECK: hlfir.elsewhere mask { |
| ! CHECK: %[[VAL_129:.*]] = hlfir.exactly_once : !hlfir.expr<100x!fir.logical<4>> { |
| ! CHECK: %[[VAL_139:.*]] = fir.call @llvm.stacksave.p0() fastmath<contract> : () -> !fir.ref<i8> |
| ! CHECK: %[[VAL_141:.*]] = fir.call @_QPpure_logical_func2() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>> |
| ! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup { |
| ! CHECK: fir.call @llvm.stackrestore.p0(%[[VAL_139]]) fastmath<contract> : (!fir.ref<i8>) -> () |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: hlfir.yield %[[VAL_129]] : !hlfir.expr<100x!fir.logical<4>> |
| ! CHECK: } do { |
| ! CHECK: hlfir.region_assign { |
| ! CHECK: hlfir.designate |
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> |
| ! CHECK: } to { |
| ! CHECK: %[[VAL_165:.*]] = hlfir.exactly_once : i32 { |
| ! CHECK: %[[VAL_166:.*]] = fir.call @_QPpure_ifoo() fastmath<contract> : () -> i32 |
| ! CHECK: hlfir.yield %[[VAL_166]] : i32 |
| ! CHECK: } |
| ! CHECK: hlfir.designate |
| ! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>> |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: } |
| ! CHECK: return |
| ! CHECK: } |