Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Lower / HLFIR / sum.f90
blob32a2423da698d23231cc6abe2fc10863b8c44082
1 ! Test lowering of SUM intrinsic to HLFIR
2 ! RUN: bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
4 ! simple 1 argument SUM
5 subroutine sum1(a, s)
6 integer :: a(:), s
7 s = SUM(a)
8 end subroutine
9 ! CHECK-LABEL: func.func @_QPsum1(
10 ! CHECK: %[[ARG0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<i32>
11 ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]]
12 ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]]
13 ! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 {fastmath = #arith.fastmath<contract>} : (!fir.box<!fir.array<?xi32>>) ->
14 !hlfir.expr<i32>
15 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<i32>, !fir.ref<i32>
16 ! CHECK-NEXT: hlfir.destroy %[[EXPR]]
17 ! CHECK-NEXT: return
18 ! CHECK-NEXT: }
20 ! sum with by-ref DIM argument
21 subroutine sum2(a, s, d)
22 integer :: a(:,:), s(:), d
23 s = SUM(a, d)
24 end subroutine
25 ! CHECK-LABEL: func.func @_QPsum2(
26 ! CHECK: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref<i32>
27 ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]]
28 ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]]
29 ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]]
30 ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref<i32>
31 ! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath<contract>} : (!fir.box<!fir.array<?x?xi32>>, i32) -> !hlfir.expr<?xi32>
32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
33 ! CHECK-NEXT: hlfir.destroy %[[EXPR]]
34 ! CHECK-NEXT: return
35 ! CHECK-NEXT: }
37 ! sum with scalar mask argument
38 subroutine sum3(a, s, m)
39 integer :: a(:), s
40 logical :: m
41 s = SUM(a, m)
42 end subroutine
43 ! CHECK-LABEL: func.func @_QPsum3(
44 ! CHECK: %[[ARG0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref<!fir.logical<4>>
45 ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]]
46 ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]]
47 ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]]
48 ! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath<contract>} : (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.logical<4>>) -> !hlfir.expr<i32>
49 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<i32>, !fir.ref<i32>
50 ! CHECK-NEXT: hlfir.destroy %[[EXPR]]
51 ! CHECK-NEXT: return
52 ! CHECK-NEXT: }
54 ! sum with array mask argument
55 subroutine sum4(a, s, m)
56 integer :: a(:), s
57 logical :: m(:)
58 s = SUM(a, m)
59 end subroutine
60 ! CHECK-LABEL: func.func @_QPsum4(
61 ! CHECK: %[[ARG0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.box<!fir.array<?x!fir.logical<4>>>
62 ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]]
63 ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]]
64 ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]]
65 ! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath<contract>} : (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?x!fir.logical<4>>>) -> !hlfir.expr<i32>
66 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<i32>, !fir.ref<i32>
67 ! CHECK-NEXT: hlfir.destroy %[[EXPR]]
68 ! CHECK-NEXT: return
69 ! CHECK-NEXT: }
71 ! sum with all 3 arguments, dim is by-val, array isn't boxed
72 subroutine sum5(s)
73 integer :: s(2)
74 integer :: a(2,2) = reshape((/1, 2, 3, 4/), [2,2])
75 s = sum(a, 1, .true.)
76 end subroutine
77 ! CHECK-LABEL: func.func @_QPsum5
78 ! CHECK: %[[ARG0:.*]]: !fir.ref<!fir.array<2xi32>>
79 ! CHECK-DAG: %[[ADDR:.*]] = fir.address_of({{.*}}) : !fir.ref<!fir.array<2x2xi32>>
80 ! CHECK-DAG: %[[ARRAY_SHAPE:.*]] = fir.shape {{.*}} -> !fir.shape<2>
81 ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ADDR]](%[[ARRAY_SHAPE]])
82 ! CHECK-DAG: %[[OUT_SHAPE:.*]] = fir.shape {{.*}} -> !fir.shape<1>
83 ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]])
84 ! CHECK-DAG: %[[TRUE:.*]] = arith.constant true
85 ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
86 ! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath<contract>} : (!fir.ref<!fir.array<2x2xi32>>, i32, i1) -> !hlfir.expr<2xi32>
87 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref<!fir.array<2xi32>>
88 ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32>
89 ! CHECK-NEXT: return
90 ! CHECK-nEXT: }
92 subroutine sum6(a, s, d)
93 integer, pointer :: d
94 real :: a(:,:), s(:)
95 s = sum(a, (d))
96 end subroutine
97 ! CHECK-LABEL: func.func @_QPsum6(
98 ! CHECK: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xf32>>
99 ! CHECK: %[[ARG1:.*]]: !fir.box<!fir.array<?xf32>>
100 ! CHECK: %[[ARG2:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>
101 ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]]
102 ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]]
103 ! CHECK-DAG: %[[DIM_VAR:.*]]:2 = hlfir.declare %[[ARG2]]
104 ! CHECK-NEXT: %[[DIM_BOX:.*]] = fir.load %[[DIM_VAR]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
105 ! CHECK-NEXT: %[[DIM_ADDR:.*]] = fir.box_addr %[[DIM_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
106 ! CHECK-NEXT: %[[DIM0:.*]] = fir.load %[[DIM_ADDR]] : !fir.ptr<i32>
107 ! CHECK-NEXT: %[[DIM1:.*]] = hlfir.no_reassoc %[[DIM0]] : i32
108 ! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 dim %[[DIM1]] {fastmath = #arith.fastmath<contract>} : (!fir.box<!fir.array<?x?xf32>>, i32) -> !hlfir.expr<?xf32>
109 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
110 ! CHECK-NEXT: hlfir.destroy %[[EXPR]]
111 ! CHECK-NEXT: return
112 ! CHECK-NEXT: }