212 lines · plain
1// RUN: tco %s | FileCheck %s2 3// CHECK-LABEL: define void @f14// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])5func.func @f1(%a : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {6 %c1 = arith.constant 1 : index7 %s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>8 %vIn = fir.array_load %a(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>9 // CHECK: = icmp sgt10 %r = fir.do_loop %j = %p to %m step %c1 iter_args(%v1 = %vIn) -> !fir.array<?x?xf32> {11 // CHECK: = icmp sgt12 %r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array<?x?xf32> {13 // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i6414 // CHECK: store float %[[F]], ptr %[[AOFF]]15 %r = fir.array_update %v, %f, %i, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>16 fir.result %r : !fir.array<?x?xf32>17 }18 fir.result %r : !fir.array<?x?xf32>19 }20 fir.array_merge_store %vIn, %r to %a : !fir.array<?x?xf32>, !fir.array<?x?xf32>, !fir.ref<!fir.array<?x?xf32>>21 // CHECK: ret void22 return23}24 25// CHECK-LABEL: define void @f226// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])27func.func @f2(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {28 %c1 = arith.constant 1 : index29 %s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>30 %vIn = fir.array_load %a(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>31 %wIn = fir.array_load %b(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>32 // CHECK: = icmp sgt33 %r = fir.do_loop %j = %p to %m step %c1 iter_args(%v1 = %vIn) -> !fir.array<?x?xf32> {34 // CHECK: = icmp sgt35 %r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array<?x?xf32> {36 %x = fir.array_fetch %wIn, %i, %j : (!fir.array<?x?xf32>, index, index) -> f3237 %y = arith.addf %x, %f : f3238 // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i6439 %r = fir.array_update %v, %y, %i, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>40 fir.result %r : !fir.array<?x?xf32>41 }42 fir.result %r : !fir.array<?x?xf32>43 }44 fir.array_merge_store %vIn, %r to %a : !fir.array<?x?xf32>, !fir.array<?x?xf32>, !fir.ref<!fir.array<?x?xf32>>45 // CHECK: ret void46 return47}48 49// CHECK-LABEL: define void @f350// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])51func.func @f3(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {52 %c1 = arith.constant 1 : index53 %s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>54 %vIn = fir.array_load %a(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>55 %wIn = fir.array_load %b(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>56 // CHECK: = icmp sgt57 %r = fir.do_loop %j = %p to %m step %c1 iter_args(%v1 = %vIn) -> !fir.array<?x?xf32> {58 // CHECK: = icmp sgt59 %r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array<?x?xf32> {60 %x = fir.array_fetch %wIn, %i, %j : (!fir.array<?x?xf32>, index, index) -> f3261 %y = arith.addf %x, %f : f3262 // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i6463 %i2 = arith.addi %i, %c1 : index64 %r = fir.array_update %v, %y, %i2, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>65 fir.result %r : !fir.array<?x?xf32>66 }67 fir.result %r : !fir.array<?x?xf32>68 }69 fir.array_merge_store %vIn, %r to %a : !fir.array<?x?xf32>, !fir.array<?x?xf32>, !fir.ref<!fir.array<?x?xf32>>70 // CHECK: ret void71 return72}73 74// CHECK-LABEL: define void @f475// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])76func.func @f4(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {77 %c1 = arith.constant 1 : index78 %s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>79 %vIn = fir.array_load %a(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>80 %wIn = fir.array_load %b(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>81 // CHECK: = icmp sgt82 %r = fir.do_loop %j = %p to %m step %c1 iter_args(%v1 = %vIn) -> !fir.array<?x?xf32> {83 // CHECK: = icmp sgt84 %r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array<?x?xf32> {85 %x2 = fir.array_fetch %vIn, %i, %j : (!fir.array<?x?xf32>, index, index) -> f3286 %x = fir.array_fetch %wIn, %i, %j : (!fir.array<?x?xf32>, index, index) -> f3287 %y = arith.addf %x, %f : f3288 %y2 = arith.addf %y, %x2 : f3289 // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i6490 %i2 = arith.addi %i, %c1 : index91 %r = fir.array_update %v, %y2, %i2, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>92 fir.result %r : !fir.array<?x?xf32>93 }94 fir.result %r : !fir.array<?x?xf32>95 }96 fir.array_merge_store %vIn, %r to %a : !fir.array<?x?xf32>, !fir.array<?x?xf32>, !fir.ref<!fir.array<?x?xf32>>97 // CHECK: ret void98 return99}100 101// Array expression assignment with potentially non contiguous arrays (e.g.102// `a = b + f`, with and v assumed shapes.103// Tests that the stride from the descriptor is used.104// CHECK-LABEL: define void @f5105// CHECK: (ptr {{[^%]*}}%[[A:.*]], ptr {{[^%]*}}%[[B:.*]], float %[[F:.*]])106func.func @f5(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.box<!fir.array<?xf32>>, %arg2: f32) {107 %c0 = arith.constant 0 : index108 %c1 = arith.constant 1 : index109 %0:3 = fir.box_dims %arg0, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)110 %1 = arith.subi %0#1, %c1 : index111 %2 = fir.array_load %arg0 : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>112 %3 = fir.array_load %arg1 : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>113 // CHECK: icmp sgt114 %4 = fir.do_loop %arg3 = %c0 to %1 step %c1 iter_args(%arg4 = %2) -> (!fir.array<?xf32>) {115 // CHECK: %[[B_STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[B]], i32 0, i32 7, i32 0, i32 2116 // CHECK: %[[B_STRIDE:.*]] = load i64, ptr %[[B_STRIDE_GEP]]117 // CHECK: %[[B_DIM_OFFSET:.*]] = mul nsw i64 %{{.*}}, %[[B_STRIDE]]118 // CHECK: %[[B_OFFSET:.*]] = add nsw i64 %[[B_DIM_OFFSET]], 0119 // CHECK: %[[B_BASE_GEP:.*]] = getelementptr {{.*}}, ptr %{{.*}}, i32 0, i32 0120 // CHECK: %[[B_BASE:.*]] = load ptr, ptr %[[B_BASE_GEP]]121 // CHECK: %[[B_VOID_ADDR:.*]] = getelementptr i8, ptr %[[B_BASE]], i64 %[[B_OFFSET]]122 // CHECK: %[[B_VAL:.*]] = load float, ptr %[[B_VOID_ADDR]]123 // CHECK: fadd float %[[B_VAL]], %[[F]]124 %5 = fir.array_fetch %3, %arg3 : (!fir.array<?xf32>, index) -> f32125 %6 = arith.addf %5, %arg2 : f32126 %7 = fir.array_update %arg4, %6, %arg3 : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>127 fir.result %7 : !fir.array<?xf32>128 }129 fir.array_merge_store %2, %4 to %arg0 : !fir.array<?xf32>, !fir.array<?xf32>, !fir.box<!fir.array<?xf32>>130 // CHECK: ret void131 return132}133 134// Overlapping array expression assignment with a potentially non135// contiguous array (e.g. `a(2:10:1) = a(1:9:1) + f`, with a assumed shape).136// Test that a temp is created.137// CHECK-LABEL: define void @f6138// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], float %[[F:.*]])139func.func @f6(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) {140 %c0 = arith.constant 0 : index141 %c1 = arith.constant 1 : index142 %c2 = arith.constant 2 : index143 %c9 = arith.constant 9 : index144 %c10 = arith.constant 10 : index145 146 // CHECK: %[[EXT_GEP:.*]] = getelementptr {{.*}} %[[A]], i32 0, i32 7, i64 0, i32 1147 // CHECK: %[[EXTENT:.*]] = load i64, ptr %[[EXT_GEP]]148 // CHECK: %[[SIZE:.*]] = mul i64 4, %[[EXTENT]]149 // CHECK: %[[CMP:.*]] = icmp sgt i64 %[[SIZE]], 0150 // CHECK: %[[SZ:.*]] = select i1 %[[CMP]], i64 %[[SIZE]], i64 1151 // CHECK: %[[MALLOC:.*]] = call ptr @malloc(i64 %[[SZ]])152 %1 = fir.slice %c2, %c10, %c1 : (index, index, index) -> !fir.slice<1>153 %2 = fir.array_load %arg0 [%1] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>) -> !fir.array<?xf32>154 %3 = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>155 %4 = fir.array_load %arg0 [%3] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>) -> !fir.array<?xf32>156 %5 = fir.do_loop %arg2 = %c0 to %c9 step %c1 iter_args(%arg3 = %2) -> (!fir.array<?xf32>) {157 %6 = fir.array_fetch %4, %arg2 : (!fir.array<?xf32>, index) -> f32158 %7 = arith.addf %6, %arg1 : f32159 %8 = fir.array_update %arg3, %7, %arg2 : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>160 fir.result %8 : !fir.array<?xf32>161 }162 fir.array_merge_store %2, %5 to %arg0[%1] : !fir.array<?xf32>, !fir.array<?xf32>, !fir.box<!fir.array<?xf32>>, !fir.slice<1>163 // CHECK: ret void164 return165}166 167// Non contiguous array with lower bounds (x = y(100), with y(4:))168// Test array_coor offset computation.169// CHECK-LABEL: define void @f7(170// CHECK: ptr {{[^%]*}}%[[X:[^,]*]], ptr {{[^%]*}}%[[Y:.*]])171func.func @f7(%arg0: !fir.ref<f32>, %arg1: !fir.box<!fir.array<?xf32>>) {172 %c4 = arith.constant 4 : index173 %c100 = arith.constant 100 : index174 %0 = fir.shift %c4 : (index) -> !fir.shift<1>175 // CHECK: %[[STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[Y]], i32 0, i32 7, i32 0, i32 2176 // CHECK: %[[STRIDE:.*]] = load i64, ptr %[[STRIDE_GEP]]177 // CHECK: mul nsw i64 96, %[[STRIDE]]178 %1 = fir.array_coor %arg1(%0) %c100 : (!fir.box<!fir.array<?xf32>>, !fir.shift<1>, index) -> !fir.ref<f32>179 %2 = fir.load %1 : !fir.ref<f32>180 fir.store %2 to %arg0 : !fir.ref<f32>181 return182} 183 184// Test A(:, :)%x reference codegen with A constant shape.185// CHECK-LABEL: define void @f8(186// CHECK-SAME: ptr {{[^%]*}}%[[A:.*]], i32 %[[I:.*]])187func.func @f8(%a : !fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, %i : i32) {188 %c0 = arith.constant 0 : index189 %c1 = arith.constant 1 : index190 %c2 = arith.constant 2 : index191 %1 = fir.field_index i, !fir.type<t{i:i32}>192 %2 = fir.shape %c2, %c2 : (index, index) -> !fir.shape<2>193 %3 = fir.slice %c1, %c2, %c1, %c1, %c2, %c1 path %1 : (index, index, index, index, index, index, !fir.field) -> !fir.slice<2>194 // CHECK: %[[GEP:.*]] = getelementptr %t, ptr %[[A]], i64 0, i32 0195 %4 = fir.array_coor %a(%2) [%3] %c1, %c1 : (!fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>196 // CHECK: store i32 %[[I]], ptr %[[GEP]], align 4197 fir.store %i to %4 : !fir.ref<i32>198 return199}200 201// Test casts in in array_coor offset computation when type parameters are not i64202// CHECK-LABEL: define ptr @f9(203// CHECK-SAME: i32 %[[I:.*]], i64 %{{.*}}, i64 %{{.*}}, ptr {{[^%]*}}%[[C:.*]])204func.func @f9(%i: i32, %e : i64, %j: i64, %c: !fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.char<1,?>> {205 %s = fir.shape %e, %e : (i64, i64) -> !fir.shape<2>206 // CHECK: %[[CAST:.*]] = sext i32 %[[I]] to i64207 // CHECK: %[[OFFSET:.*]] = mul nsw i64 %{{.*}}, %[[CAST]]208 // CHECK: getelementptr i8, ptr %[[C]], i64 %[[OFFSET]]209 %a = fir.array_coor %c(%s) %j, %j typeparams %i : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i64, i64, i32) -> !fir.ref<!fir.char<1,?>>210 return %a : !fir.ref<!fir.char<1,?>>211}212