| // Test conversions of fir.alloca |
| // RUN: fir-opt %s --fir-to-memref --allow-unregistered-dialect | FileCheck %s |
| |
| // Test that compiler generated fir.allocas are converted, slightly edited from |
| // subroutine alloca(a) |
| // call f(1) |
| // end |
| |
| // CHECK-LABEL: func.func @alloca |
| // CHECK: [[ALLOCA:%.+]] = memref.alloca() : memref<i32> |
| // CHECK-NEXT: [[CONVERT0:%[0-9]]] = fir.convert [[ALLOCA]] : (memref<i32>) -> !fir.ref<i32> |
| // CHECK: [[CONSTANT:%.+]] = arith.constant 1 : i32 |
| // CHECK: memref.store [[CONSTANT]], [[ALLOCA]][] : memref<i32> |
| // CHECK: fir.call @f([[CONVERT0]]) |
| |
| func.func @alloca(%arg0: !fir.ref<f32> {fir.bindc_name = "a"}) { |
| %0 = fir.alloca i32 {adapt.valuebyref} |
| %c1_i32 = arith.constant 1 : i32 |
| %1 = fir.dummy_scope : !fir.dscope |
| %2 = fir.declare %arg0 dummy_scope %1 {uniq_name = "alloca"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32> |
| fir.store %c1_i32 to %0 : !fir.ref<i32> |
| %false = arith.constant false |
| fir.call @f(%0) fastmath<contract> : (!fir.ref<i32>) -> () |
| return |
| } |
| func.func private @f(!fir.ref<i32>) |
| |
| // Test that compiler generated fir.allocas are converted, slightly edited from |
| // subroutine passbyvalue(x) |
| // integer, value :: x |
| // end subroutine |
| |
| // CHECK-LABEL: func.func @passbyvalue |
| // CHECK: [[ALLOCA:%.+]] = memref.alloca() : memref<i32> |
| // CHECK-NEXT: [[CONVERT0:%[0-9]]] = fir.convert [[ALLOCA]] : (memref<i32>) -> !fir.ref<i32> |
| // CHECK-NEXT: memref.store %arg0, [[ALLOCA]][] : memref<i32> |
| |
| func.func @passbyvalue(%arg0: i32 {fir.bindc_name = "x"}) { |
| %0 = fir.dummy_scope : !fir.dscope |
| %1 = fir.alloca i32 |
| fir.store %arg0 to %1 : !fir.ref<i32> |
| %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFpEx"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> |
| return |
| } |
| |
| // Multi-dim dynamic alloca, reduced from |
| // subroutine alloca_2d(n,m) |
| // real :: a(n,m) |
| // end |
| |
| // CHECK-LABEL: func.func @_QPalloca_2d |
| // CHECK: [[CON5:%.+]] = arith.constant 5 |
| // CHECK-NEXT: [[CON3:%.+]] = arith.constant 3 |
| // CHECK-NEXT: [[ALLOCA:%.+]] = memref.alloca([[CON3]], [[CON5]]) {bindc_name = "a"} : memref<?x?xf32> |
| // CHECK-NEXT: [[CONVERT0:%[0-9]]] = fir.convert [[ALLOCA]] : (memref<?x?xf32>) -> !fir.ref<!fir.array<?x?xf32>> |
| |
| func.func @_QPalloca_2d() { |
| %0 = arith.constant 5 : index |
| %1 = arith.constant 3 : index |
| %2 = fir.alloca !fir.array<?x?xf32>, %0, %1 {bindc_name = "a"} |
| return |
| } |
| |
| // CHECK-LABEL: func.func @alloca_nonconvertible |
| // CHECK-NEXT: [[ALLOCA1:%.+]] = fir.alloca |
| // CHECK-NEXT: [[ALLOCA2:%.+]] = memref.alloca |
| // CHECK-NEXT: [[CONVERT0:%[0-9]]] = fir.convert [[ALLOCA2]] : (memref<i32>) -> !fir.ref<i32> |
| func.func @alloca_nonconvertible() { |
| %0 = fir.alloca !fir.box<!fir.array<20xi32>> |
| %1 = fir.alloca i32 |
| return |
| } |
| |
| // compiler generated alloca will not preserve declare |
| // CHECK-LABEL: func.func @peep_declare |
| // CHECK: [[ALLOCA:%.+]] = memref.alloca() : memref<i32> |
| // CHECK-NOT: fir.declare |
| // CHECK: memref.store %c1_i32, [[ALLOCA]][] : memref<i32> |
| func.func @peep_declare() { |
| %c1_i32 = arith.constant 1 : i32 |
| %0 = fir.alloca i32 |
| %1 = fir.declare %0 {uniq_name = "some_name"} : (!fir.ref<i32>) -> !fir.ref<i32> |
| fir.store %c1_i32 to %1 : !fir.ref<i32> |
| return |
| } |
| |
| // check that attributes are copied when they exist |
| // CHECK-LABEL: func.func @preserve_declare |
| // CHECK: [[ALLOCA:%.*]] = memref.alloca() {bindc_name = "x", uniq_name = "y"} : memref<i32> |
| // CHECK-NOT: memref.store %c1_i32, [[ALLOCA]][] : memref<i32> |
| func.func @preserve_declare() { |
| %c1_i32 = arith.constant 1 : i32 |
| %0 = fir.alloca i32 {bindc_name = "x", uniq_name = "y"} |
| %1 = fir.declare %0 {uniq_name = "some_name"} : (!fir.ref<i32>) -> !fir.ref<i32> |
| fir.store %c1_i32 to %1 : !fir.ref<i32> |
| return |
| } |
| |
| // CHECK-LABEL: func.func @copy_cuf_data_attr |
| // CHECK: memref.alloca() {cuf.data_attr = #cuf.cuda<device>} : memref<i32> |
| func.func @copy_cuf_data_attr() { |
| %c1_i32 = arith.constant 1 : i32 |
| %0 = fir.alloca i32 {cuf.data_attr = #cuf.cuda<device>} |
| %1 = fir.declare %0 {uniq_name = "some_name"} : (!fir.ref<i32>) -> !fir.ref<i32> |
| fir.store %c1_i32 to %1 : !fir.ref<i32> |
| return |
| } |
| |
| // CHECK-LABEL: func.func @copy_acc_var_name_attr |
| // CHECK: memref.alloca() {acc.var_name = #acc.var_name<"x">} : memref<i32> |
| func.func @copy_acc_var_name_attr() { |
| %c1_i32 = arith.constant 1 : i32 |
| %0 = fir.alloca i32 {acc.var_name = #acc.var_name<"x">} |
| %1 = fir.declare %0 {uniq_name = "some_name"} : (!fir.ref<i32>) -> !fir.ref<i32> |
| fir.store %c1_i32 to %1 : !fir.ref<i32> |
| return |
| } |