[LLVM] Fix Maintainers.md formatting (NFC)
[llvm-project.git] / flang / test / HLFIR / simplify-hlfir-intrinsics.fir
blobaeea8bfc97326629bed9e7f483ca5c0bd5f77acd
1 // RUN: fir-opt --simplify-hlfir-intrinsics %s | FileCheck %s
3 // box with known extents
4 func.func @transpose0(%arg0: !fir.box<!fir.array<1x2xi32>>) {
5   %res = hlfir.transpose %arg0 : (!fir.box<!fir.array<1x2xi32>>) -> !hlfir.expr<2x1xi32>
6   return
8 // CHECK-LABEL:   func.func @transpose0(
9 // CHECK-SAME:                          %[[ARG0:.*]]: !fir.box<!fir.array<1x2xi32>>) {
10 // CHECK:           %[[C1:.*]] = arith.constant 1 : index
11 // CHECK:           %[[C2:.*]] = arith.constant 2 : index
12 // CHECK:           %[[SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2>
13 // CHECK:           %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x1xi32> {
14 // CHECK:           ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
15 // CHECK:             %[[C0:.*]] = arith.constant 0 : index
16 // CHECK:             %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<1x2xi32>>, index) -> (index, index, index)
17 // CHECK:             %[[C1_1:.*]] = arith.constant 1 : index
18 // CHECK:             %[[DIMS1:.*]]:3 = fir.box_dims %[[ARG0]], %[[C1_1]] : (!fir.box<!fir.array<1x2xi32>>, index) -> (index, index, index)
19 // CHECK:             %[[C1_2:.*]] = arith.constant 1 : index
20 // CHECK:             %[[LOWER_BOUND0:.*]] = arith.subi %[[DIMS0]]#0, %[[C1_2]] : index
21 // CHECK:             %[[J_OFFSET:.*]] = arith.addi %[[J]], %[[LOWER_BOUND0]] : index
22 // CHECK:             %[[LOWER_BOUND1:.*]] = arith.subi %[[DIMS1]]#0, %[[C1_2]] : index
23 // CHECK:             %[[I_OFFSET:.*]] = arith.addi %[[I]], %[[LOWER_BOUND1]] : index
24 // CHECK:             %[[ELEMENT_REF:.*]] = hlfir.designate %[[ARG0]] (%[[J_OFFSET]], %[[I_OFFSET]])  : (!fir.box<!fir.array<1x2xi32>>, index, index) -> !fir.ref<i32>
25 // CHECK:             %[[ELEMENT:.*]] = fir.load %[[ELEMENT_REF]] : !fir.ref<i32>
26 // CHECK:             hlfir.yield_element %[[ELEMENT]] : i32
27 // CHECK:           }
28 // CHECK:           return
29 // CHECK:         }
31 // expr with known extents
32 func.func @transpose1(%arg0: !hlfir.expr<1x2xi32>) {
33   %res = hlfir.transpose %arg0 : (!hlfir.expr<1x2xi32>) -> !hlfir.expr<2x1xi32>
34   return
36 // CHECK-LABEL:   func.func @transpose1(
37 // CHECK-SAME:                          %[[ARG0:.*]]: !hlfir.expr<1x2xi32>) {
38 // CHECK:           %[[C1:.*]] = arith.constant 1 : index
39 // CHECK:           %[[C2:.*]] = arith.constant 2 : index
40 // CHECK:           %[[SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2>
41 // CHECK:           %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x1xi32> {
42 // CHECK:           ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
43 // CHECK:             %[[ELEMENT:.*]] = hlfir.apply %[[ARG0]], %[[J]], %[[I]] : (!hlfir.expr<1x2xi32>, index, index) -> i32
44 // CHECK:             hlfir.yield_element %[[ELEMENT]] : i32
45 // CHECK:           }
46 // CHECK:           return
47 // CHECK:         }
49 // box with unknown extent
50 func.func @transpose2(%arg0: !fir.box<!fir.array<?x2xi32>>) {
51   %res = hlfir.transpose %arg0 : (!fir.box<!fir.array<?x2xi32>>) -> !hlfir.expr<2x?xi32>
52   return
54 // CHECK-LABEL:   func.func @transpose2(
55 // CHECK-SAME:                          %[[ARG0:.*]]: !fir.box<!fir.array<?x2xi32>>) {
56 // CHECK:           %[[C0:.*]] = arith.constant 0 : index
57 // CHECK:           %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<?x2xi32>>, index) -> (index, index, index)
58 // CHECK:           %[[C2:.*]] = arith.constant 2 : index
59 // CHECK:           %[[SHAPE:.*]] = fir.shape %[[C2]], %[[DIMS0]]#1 : (index, index) -> !fir.shape<2>
60 // CHECK:           %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> {
61 // CHECK:           ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
62 // CHECK:             %[[C0_1:.*]] = arith.constant 0 : index
63 // CHECK:             %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0_1]] : (!fir.box<!fir.array<?x2xi32>>, index) -> (index, index, index)
64 // CHECK:             %[[C1_1:.*]] = arith.constant 1 : index
65 // CHECK:             %[[DIMS1_1:.*]]:3 = fir.box_dims %[[ARG0]], %[[C1_1]] : (!fir.box<!fir.array<?x2xi32>>, index) -> (index, index, index)
66 // CHECK:             %[[C1_2:.*]] = arith.constant 1 : index
67 // CHECK:             %[[LOWER_BOUND0:.*]] = arith.subi %[[DIMS0]]#0, %[[C1_2]] : index
68 // CHECK:             %[[J_OFFSET:.*]] = arith.addi %[[J]], %[[LOWER_BOUND0]] : index
69 // CHECK:             %[[LOWER_BOUND1:.*]] = arith.subi %[[DIMS1_1]]#0, %[[C1_2]] : index
70 // CHECK:             %[[I_OFFSET:.*]] = arith.addi %[[I]], %[[LOWER_BOUND1]] : index
71 // CHECK:             %[[ELE_REF:.*]] = hlfir.designate %[[ARG0]] (%[[J_OFFSET]], %[[I_OFFSET]])  : (!fir.box<!fir.array<?x2xi32>>, index, index) -> !fir.ref<i32>
72 // CHECK:             %[[ELEMENT:.*]] = fir.load %[[ELE_REF]] : !fir.ref<i32>
73 // CHECK:             hlfir.yield_element %[[ELEMENT]] : i32
74 // CHECK:           }
75 // CHECK:           return
76 // CHECK:         }
78 // expr with unknown extent
79 func.func @transpose3(%arg0: !hlfir.expr<?x2xi32>) {
80   %res = hlfir.transpose %arg0 : (!hlfir.expr<?x2xi32>) -> !hlfir.expr<2x?xi32>
81   return
83 // CHECK-LABEL:   func.func @transpose3(
84 // CHECK-SAME:                          %[[ARG0:.*]]: !hlfir.expr<?x2xi32>) {
85 // CHECK:           %[[IN_SHAPE:.*]] = hlfir.shape_of %[[ARG0]] : (!hlfir.expr<?x2xi32>) -> !fir.shape<2>
86 // CHECK:           %[[EXTENT0:.*]] = hlfir.get_extent %[[IN_SHAPE]] {dim = 0 : index} : (!fir.shape<2>) -> index
87 // CHECK:           %[[C2:.*]] = arith.constant 2 : index
88 // CHECK:           %[[OUT_SHAPE:.*]] = fir.shape %[[C2]], %[[EXTENT0]] : (index, index) -> !fir.shape<2>
89 // CHECK:           %[[EXPR:.*]] = hlfir.elemental %[[OUT_SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> {
90 // CHECK:           ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
91 // CHECK:             %[[ELEMENT:.*]] = hlfir.apply %[[ARG0]], %[[J]], %[[I]] : (!hlfir.expr<?x2xi32>, index, index) -> i32
92 // CHECK:             hlfir.yield_element %[[ELEMENT]] : i32
93 // CHECK:           }
94 // CHECK:           return
95 // CHECK:         }
97 // expr with multiple uses
98 func.func @transpose4(%arg0: !hlfir.expr<2x2xf32>, %arg1: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>) {
99   %0 = hlfir.transpose %arg0 : (!hlfir.expr<2x2xf32>) -> !hlfir.expr<2x2xf32>
100   %1 = hlfir.shape_of %0 : (!hlfir.expr<2x2xf32>) -> !fir.shape<2>
101   %2 = hlfir.elemental %1 : (!fir.shape<2>) -> !hlfir.expr<2x2xf32> {
102   ^bb0(%arg2: index, %arg3: index):
103     %3 = hlfir.apply %0, %arg2, %arg3 : (!hlfir.expr<2x2xf32>, index, index) -> f32
104     %4 = math.cos %3 fastmath<contract> : f32
105     hlfir.yield_element %4 : f32
106   }
107   hlfir.assign %2 to %arg1 realloc : !hlfir.expr<2x2xf32>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
108   hlfir.destroy %2 : !hlfir.expr<2x2xf32>
109   hlfir.destroy %0 : !hlfir.expr<2x2xf32>
110   return
112 // CHECK-LABEL: func.func @transpose4(
113 // CHECK-SAME:      %[[ARG0:.*]]: !hlfir.expr<2x2xf32>
114 // CHECK-SAME:      %[[ARG1:.*]]:
115 // CHECK:         %[[SHAPE0:.*]] = fir.shape
116 // CHECK:         %[[TRANSPOSE:.*]] = hlfir.elemental %[[SHAPE0]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x2xf32> {
117 // CHECK:         ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
118 // CHECK:           %[[ELE:.*]] = hlfir.apply %[[ARG0]], %[[J]], %[[I]] : (!hlfir.expr<2x2xf32>, index, index) -> f32
119 // CHECK:           hlfir.yield_element %[[ELE]] : f32
120 // CHECK:         }
121 // CHECK:         %[[SHAPE1:.*]] = hlfir.shape_of %[[TRANSPOSE]] : (!hlfir.expr<2x2xf32>) -> !fir.shape<2>
122 // CHECK:         %[[COS:.*]] = hlfir.elemental %[[SHAPE1]] : (!fir.shape<2>) -> !hlfir.expr<2x2xf32> {
123 // CHECK:         ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
124 // CHECK:           %[[ELE:.*]] = hlfir.apply %[[TRANSPOSE]], %[[I]], %[[J]] : (!hlfir.expr<2x2xf32>, index, index) -> f32
125 // CHECK:           %[[COS_ELE:.*]] = math.cos %[[ELE]] fastmath<contract> : f32
126 // CHECK:           hlfir.yield_element %[[COS_ELE]] : f32
127 // CHECK:         }
128 // CHECK:         hlfir.assign %[[COS]] to %[[ARG1]] realloc
129 // CHECK:         hlfir.destroy %[[COS]] : !hlfir.expr<2x2xf32>
130 // CHECK:         hlfir.destroy %[[TRANSPOSE]] : !hlfir.expr<2x2xf32>
131 // CHECK:         return
132 // CHECK:       }
134 // regression test
135 func.func @transpose5(%arg0: !fir.ref<tuple<!fir.box<!fir.array<2x2xf64>>, !fir.box<!fir.array<2x2xf64>>>> {fir.host_assoc}) attributes {fir.internal_proc} {
136   %0 = fir.address_of(@_QFEb) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>
137   %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>)
138   %c0_i32 = arith.constant 0 : i32
139   %2 = fir.coordinate_of %arg0, %c0_i32 : (!fir.ref<tuple<!fir.box<!fir.array<2x2xf64>>, !fir.box<!fir.array<2x2xf64>>>>, i32) -> !fir.ref<!fir.box<!fir.array<2x2xf64>>>
140   %3 = fir.load %2 : !fir.ref<!fir.box<!fir.array<2x2xf64>>>
141   %4 = fir.box_addr %3 : (!fir.box<!fir.array<2x2xf64>>) -> !fir.ref<!fir.array<2x2xf64>>
142   %c0 = arith.constant 0 : index
143   %5:3 = fir.box_dims %3, %c0 : (!fir.box<!fir.array<2x2xf64>>, index) -> (index, index, index)
144   %c1 = arith.constant 1 : index
145   %6:3 = fir.box_dims %3, %c1 : (!fir.box<!fir.array<2x2xf64>>, index) -> (index, index, index)
146   %7 = fir.shape %5#1, %6#1 : (index, index) -> !fir.shape<2>
147   %8:2 = hlfir.declare %4(%7) {uniq_name = "_QFEa"} : (!fir.ref<!fir.array<2x2xf64>>, !fir.shape<2>) -> (!fir.ref<!fir.array<2x2xf64>>, !fir.ref<!fir.array<2x2xf64>>)
148   %c1_i32 = arith.constant 1 : i32
149   %9 = fir.coordinate_of %arg0, %c1_i32 : (!fir.ref<tuple<!fir.box<!fir.array<2x2xf64>>, !fir.box<!fir.array<2x2xf64>>>>, i32) -> !fir.ref<!fir.box<!fir.array<2x2xf64>>>
150   %10 = fir.load %9 : !fir.ref<!fir.box<!fir.array<2x2xf64>>>
151   %11 = fir.box_addr %10 : (!fir.box<!fir.array<2x2xf64>>) -> !fir.ref<!fir.array<2x2xf64>>
152   %c0_0 = arith.constant 0 : index
153   %12:3 = fir.box_dims %10, %c0_0 : (!fir.box<!fir.array<2x2xf64>>, index) -> (index, index, index)
154   %c1_1 = arith.constant 1 : index
155   %13:3 = fir.box_dims %10, %c1_1 : (!fir.box<!fir.array<2x2xf64>>, index) -> (index, index, index)
156   %14 = fir.shape %12#1, %13#1 : (index, index) -> !fir.shape<2>
157   %15:2 = hlfir.declare %11(%14) {uniq_name = "_QFEc"} : (!fir.ref<!fir.array<2x2xf64>>, !fir.shape<2>) -> (!fir.ref<!fir.array<2x2xf64>>, !fir.ref<!fir.array<2x2xf64>>)
158   %16 = hlfir.transpose %8#0 : (!fir.ref<!fir.array<2x2xf64>>) -> !hlfir.expr<2x2xf64>
159   %17 = hlfir.shape_of %16 : (!hlfir.expr<2x2xf64>) -> !fir.shape<2>
160   %18 = hlfir.elemental %17 : (!fir.shape<2>) -> !hlfir.expr<?x?xf64> {
161   ^bb0(%arg1: index, %arg2: index):
162     %19 = hlfir.apply %16, %arg1, %arg2 : (!hlfir.expr<2x2xf64>, index, index) -> f64
163     %20 = math.cos %19 fastmath<contract> : f64
164     hlfir.yield_element %20 : f64
165   }
166   hlfir.assign %18 to %1#0 realloc : !hlfir.expr<?x?xf64>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>
167   hlfir.destroy %18 : !hlfir.expr<?x?xf64>
168   hlfir.destroy %16 : !hlfir.expr<2x2xf64>
169   return
171 // CHECK-LABEL: func.func @transpose5(
172 // ...
173 // CHECK:         %[[TRANSPOSE:.*]] = hlfir.elemental %[[SHAPE0:.*]]
174 // CHECK:         ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
175 // CHECK:           %[[ELE:.*]] = hlfir.designate %[[ARRAY:.*]] (%[[J]], %[[I]])
176 // CHECK:           %[[LOAD:.*]] = fir.load %[[ELE]]
177 // CHECK:           hlfir.yield_element %[[LOAD]]
178 // CHECK:         }
179 // CHECK:         %[[SHAPE1:.*]] = hlfir.shape_of %[[TRANSPOSE]]
180 // CHECK:         %[[COS:.*]] = hlfir.elemental %[[SHAPE1]]
181 // ...
182 // CHECK:         hlfir.assign %[[COS]] to %{{.*}} realloc
183 // CHECK:         hlfir.destroy %[[COS]]
184 // CHECK:         hlfir.destroy %[[TRANSPOSE]]
185 // CHECK:         return
186 // CHECK:       }