aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flang/include/flang/Optimizer/Dialect/FIROps.td12
-rw-r--r--flang/lib/Optimizer/Analysis/AliasAnalysis.cpp57
-rw-r--r--flang/test/Driver/tco-emit-final-mlir.fir2
-rw-r--r--flang/test/Fir/alloc.fir9
-rw-r--r--flang/test/Fir/omp-reduction-embox-codegen.fir2
-rw-r--r--flang/test/Fir/pdt.fir6
-rw-r--r--flang/test/HLFIR/inline-hlfir-copy-in.fir2
-rw-r--r--flang/test/Lower/Intrinsics/c_f_pointer.f901
-rw-r--r--flang/test/Lower/Intrinsics/system_clock.f902
-rw-r--r--flang/test/Lower/allocatables.f906
-rw-r--r--flang/test/Lower/character-local-variables.f9011
-rw-r--r--flang/test/Lower/derived-types.f902
-rw-r--r--flang/test/Lower/do_loop_unstructured.f901
-rw-r--r--flang/test/Lower/forall/array-pointer.f901
-rw-r--r--flang/test/Lower/forall/forall-allocatable.f9017
-rw-r--r--flang/test/Lower/loops.f901
-rw-r--r--flang/test/Lower/polymorphic.f904
-rw-r--r--flang/test/Lower/statement-function.f901
-rw-r--r--flang/test/Transforms/stack-arrays.fir131
19 files changed, 172 insertions, 96 deletions
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index bae52d6..289c79b 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -80,8 +80,7 @@ def AnyRefOfConstantSizeAggregateType : TypeConstraint<
// Memory SSA operations
//===----------------------------------------------------------------------===//
-def fir_AllocaOp : fir_Op<"alloca", [AttrSizedOperandSegments,
- MemoryEffects<[MemAlloc<AutomaticAllocationScopeResource>]>]> {
+def fir_AllocaOp : fir_Op<"alloca", [AttrSizedOperandSegments]> {
let summary = "allocate storage for a temporary on the stack given a type";
let description = [{
This primitive operation is used to allocate an object on the stack. A
@@ -162,7 +161,9 @@ def fir_AllocaOp : fir_Op<"alloca", [AttrSizedOperandSegments,
Variadic<AnyIntegerType>:$shape
);
- let results = (outs fir_ReferenceType);
+ let results =
+ (outs Res<fir_ReferenceType,
+ "", [MemAlloc<AutomaticAllocationScopeResource>]>:$res);
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
@@ -212,8 +213,7 @@ def fir_AllocaOp : fir_Op<"alloca", [AttrSizedOperandSegments,
}];
}
-def fir_AllocMemOp : fir_Op<"allocmem",
- [MemoryEffects<[MemAlloc<DefaultResource>]>, AttrSizedOperandSegments]> {
+def fir_AllocMemOp : fir_Op<"allocmem", [AttrSizedOperandSegments]> {
let summary = "allocate storage on the heap for an object of a given type";
let description = [{
@@ -235,7 +235,7 @@ def fir_AllocMemOp : fir_Op<"allocmem",
Variadic<AnyIntegerType>:$typeparams,
Variadic<AnyIntegerType>:$shape
);
- let results = (outs fir_HeapType);
+ let results = (outs Res<fir_HeapType, "", [MemAlloc<DefaultResource>]>:$res);
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 73ddd1f..ef98942 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -27,6 +27,26 @@ using namespace mlir;
#define DEBUG_TYPE "fir-alias-analysis"
+// Inspect for value-scoped Allocate effects and determine whether
+// 'candidate' is a new allocation. Returns SourceKind::Allocate if a
+// MemAlloc effect is attached
+static fir::AliasAnalysis::SourceKind
+classifyAllocateFromEffects(mlir::Operation *op, mlir::Value candidate) {
+ if (!op)
+ return fir::AliasAnalysis::SourceKind::Unknown;
+ auto interface = llvm::dyn_cast<mlir::MemoryEffectOpInterface>(op);
+ if (!interface)
+ return fir::AliasAnalysis::SourceKind::Unknown;
+ llvm::SmallVector<mlir::MemoryEffects::EffectInstance, 4> effects;
+ interface.getEffects(effects);
+ for (mlir::MemoryEffects::EffectInstance &e : effects) {
+ if (mlir::isa<mlir::MemoryEffects::Allocate>(e.getEffect()) &&
+ e.getValue() && e.getValue() == candidate)
+ return fir::AliasAnalysis::SourceKind::Allocate;
+ }
+ return fir::AliasAnalysis::SourceKind::Unknown;
+}
+
//===----------------------------------------------------------------------===//
// AliasAnalysis: alias
//===----------------------------------------------------------------------===//
@@ -535,6 +555,11 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
mlir::Operation *instantiationPoint{nullptr};
while (defOp && !breakFromLoop) {
ty = defOp->getResultTypes()[0];
+ // Value-scoped allocation detection via effects.
+ if (classifyAllocateFromEffects(defOp, v) == SourceKind::Allocate) {
+ type = SourceKind::Allocate;
+ break;
+ }
llvm::TypeSwitch<Operation *>(defOp)
.Case<hlfir::AsExprOp>([&](auto op) {
v = op.getVar();
@@ -554,11 +579,6 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
defOp = v.getDefiningOp();
}
})
- .Case<fir::AllocaOp, fir::AllocMemOp>([&](auto op) {
- // Unique memory allocation.
- type = SourceKind::Allocate;
- breakFromLoop = true;
- })
.Case<fir::ConvertOp>([&](auto op) {
// Skip ConvertOp's and track further through the operand.
v = op->getOperand(0);
@@ -628,16 +648,23 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
type = SourceKind::Global;
} else {
auto def = llvm::cast<mlir::Value>(boxSrc.origin.u);
- // TODO: Add support to fir.allocmem
- if (auto allocOp = def.template getDefiningOp<fir::AllocaOp>()) {
- v = def;
- defOp = v.getDefiningOp();
- type = SourceKind::Allocate;
- } else if (isDummyArgument(def)) {
- defOp = nullptr;
- v = def;
- } else {
- type = SourceKind::Indirect;
+ bool classified = false;
+ if (auto defDefOp = def.getDefiningOp()) {
+ if (classifyAllocateFromEffects(defDefOp, def) ==
+ SourceKind::Allocate) {
+ v = def;
+ defOp = defDefOp;
+ type = SourceKind::Allocate;
+ classified = true;
+ }
+ }
+ if (!classified) {
+ if (isDummyArgument(def)) {
+ defOp = nullptr;
+ v = def;
+ } else {
+ type = SourceKind::Indirect;
+ }
}
}
breakFromLoop = true;
diff --git a/flang/test/Driver/tco-emit-final-mlir.fir b/flang/test/Driver/tco-emit-final-mlir.fir
index 75f8f15..7e934c9 100644
--- a/flang/test/Driver/tco-emit-final-mlir.fir
+++ b/flang/test/Driver/tco-emit-final-mlir.fir
@@ -15,5 +15,7 @@
func.func @_QPfoo() {
%1 = fir.alloca i32
+ %0 = arith.constant 0 : i32
+ fir.store %0 to %1 : !fir.ref<i32>
return
}
diff --git a/flang/test/Fir/alloc.fir b/flang/test/Fir/alloc.fir
index 8da8b82..613c8e2 100644
--- a/flang/test/Fir/alloc.fir
+++ b/flang/test/Fir/alloc.fir
@@ -372,8 +372,17 @@ func.func @alloca_unlimited_polymorphic_box() {
%1 = fir.alloca !fir.class<!fir.array<?xnone>>
%2 = fir.alloca !fir.box<none>
%3 = fir.alloca !fir.box<!fir.array<?xnone>>
+ // Add real uses so allocas are not trivially dead.
+ fir.call @__use_class_none(%0) : (!fir.ref<!fir.class<none>>) -> ()
+ fir.call @__use_class_array(%1) : (!fir.ref<!fir.class<!fir.array<?xnone>>>) -> ()
+ fir.call @__use_box_none(%2) : (!fir.ref<!fir.box<none>>) -> ()
+ fir.call @__use_box_array(%3) : (!fir.ref<!fir.box<!fir.array<?xnone>>>) -> ()
return
}
+func.func private @__use_class_none(!fir.ref<!fir.class<none>>) -> ()
+func.func private @__use_class_array(!fir.ref<!fir.class<!fir.array<?xnone>>>) -> ()
+func.func private @__use_box_none(!fir.ref<!fir.box<none>>) -> ()
+func.func private @__use_box_array(!fir.ref<!fir.box<!fir.array<?xnone>>>) -> ()
// Note: allocmem of fir.box are not possible (fir::HeapType::verify does not
// accept box types), so there is no equivalent of
// alloca_unlimited_polymorphic_box for allocmem.
diff --git a/flang/test/Fir/omp-reduction-embox-codegen.fir b/flang/test/Fir/omp-reduction-embox-codegen.fir
index 1645e1a..47fffb3 100644
--- a/flang/test/Fir/omp-reduction-embox-codegen.fir
+++ b/flang/test/Fir/omp-reduction-embox-codegen.fir
@@ -28,9 +28,11 @@ func.func @_QQmain() attributes {fir.bindc_name = "reduce"} {
omp.parallel reduction(byref @test_reduction %4 -> %arg0 : !fir.ref<!fir.box<i32>>) {
omp.terminator
}
+ func.call @__use_box_i32(%4) : (!fir.ref<!fir.box<i32>>) -> ()
return
}
+func.func private @__use_box_i32(!fir.ref<!fir.box<i32>>) -> ()
// basically we are testing that there isn't a crash
// CHECK-LABEL: define void @_QQmain
// CHECK-NEXT: alloca { ptr, i64, i32, i8, i8, i8, i8 }, i64 1, align 8
diff --git a/flang/test/Fir/pdt.fir b/flang/test/Fir/pdt.fir
index a200cd7..04f48e7 100644
--- a/flang/test/Fir/pdt.fir
+++ b/flang/test/Fir/pdt.fir
@@ -95,14 +95,14 @@ func.func @_QTt1P.f2.offset(%0 : i32, %1 : i32) -> i32 {
// end program p
func.func private @bar(!fir.ref<!fir.char<1,?>>)
+func.func private @__use_t1(!fir.ref<!fir.type<_QTt1(p1:i32,p2:i32){f1:!fir.char<1,?>,f2:!fir.char<1,?>}>>) -> ()
// CHECK-LABEL: define void @_QPfoo(i32 %0, i32 %1)
func.func @_QPfoo(%arg0 : i32, %arg1 : i32) {
// CHECK: %[[size:.*]] = call i64 @_QTt1P.mem.size(i32 %0, i32 %1)
// CHECK: %[[alloc:.*]] = alloca i8, i64 %[[size]]
%0 = fir.alloca !fir.type<_QTt1(p1:i32,p2:i32){f1:!fir.char<1,?>,f2:!fir.char<1,?>}>(%arg0, %arg1 : i32, i32)
- //%2 = fir.coordinate_of %0, f2 : (!fir.ref<!fir.type<_QTt1>>) -> !fir.ref<!fir.char<1,?>>
- %2 = fir.zero_bits !fir.ref<!fir.char<1,?>>
- fir.call @bar(%2) : (!fir.ref<!fir.char<1,?>>) -> ()
+ // Keep alloca live without creating an unsupported coordinate_of on dynamic-sized field.
+ func.call @__use_t1(%0) : (!fir.ref<!fir.type<_QTt1(p1:i32,p2:i32){f1:!fir.char<1,?>,f2:!fir.char<1,?>}>>) -> ()
return
}
diff --git a/flang/test/HLFIR/inline-hlfir-copy-in.fir b/flang/test/HLFIR/inline-hlfir-copy-in.fir
index f3c4b38..f1da1da 100644
--- a/flang/test/HLFIR/inline-hlfir-copy-in.fir
+++ b/flang/test/HLFIR/inline-hlfir-copy-in.fir
@@ -75,7 +75,7 @@ func.func private @_test_inline_copy_in(%arg0: !fir.box<!fir.array<?x?x?xf64>> {
// CHECK: %[[VAL_22:.*]] = fir.box_addr %[[VAL_21:.*]]#0 : (!fir.box<!fir.array<?xf64>>) -> !fir.ref<!fir.array<?xf64>>
// CHECK: %[[VAL_23:.*]]:3 = hlfir.associate %[[VAL_5:.*]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
// CHECK: fir.call @_QFPsb(%[[VAL_22:.*]], %[[VAL_23:.*]]#0) fastmath<contract> : (!fir.ref<!fir.array<?xf64>>, !fir.ref<i32>) -> ()
-// CHECK: hlfir.copy_out %16, %15#1 : (!fir.ref<!fir.box<!fir.array<?xf64>>>, i1) -> ()
+// CHECK: hlfir.copy_out %{{.*}}, %[[VAL_21:.*]]#1 : (!fir.ref<!fir.box<!fir.array<?xf64>>>, i1) -> ()
// CHECK: hlfir.end_associate %[[VAL_23:.*]]#1, %[[VAL_23:.*]]#2 : !fir.ref<i32>, i1
// CHECK: return
// CHECK: }
diff --git a/flang/test/Lower/Intrinsics/c_f_pointer.f90 b/flang/test/Lower/Intrinsics/c_f_pointer.f90
index c1f1d79..f54fda4 100644
--- a/flang/test/Lower/Intrinsics/c_f_pointer.f90
+++ b/flang/test/Lower/Intrinsics/c_f_pointer.f90
@@ -153,7 +153,6 @@ subroutine dynamic_shape_lower(cptr, fpr, shape, lower)
! CHECK: %[[VAL_2:.*]] = fir.shape %[[C_0]], %[[C_0]] : (index, index) -> !fir.shape<2>
! CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_1:.*]](%[[VAL_2]]) : (!fir.ptr<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
! CHECK: fir.store %[[VAL_3]] to %[[VAL_0:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>
-! CHECK: %[[VAL_4:.*]] = fir.alloca i32 {bindc_name = "n", uniq_name = "_QFdynamic_shape_lowerEn"}
! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[ARG_0:.*]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_5]] : !fir.ref<i64>
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i64) -> !fir.ptr<!fir.array<?x?xf32>>
diff --git a/flang/test/Lower/Intrinsics/system_clock.f90 b/flang/test/Lower/Intrinsics/system_clock.f90
index 9eae3a5..f6fae11 100644
--- a/flang/test/Lower/Intrinsics/system_clock.f90
+++ b/flang/test/Lower/Intrinsics/system_clock.f90
@@ -32,11 +32,9 @@ end subroutine
! CHECK-LABEL: @_QPss
subroutine ss(count)
- ! CHECK: %[[V_0:[0-9]+]] = fir.alloca !fir.box<!fir.heap<i64>> {bindc_name = "count_max", uniq_name = "_QFssEcount_max"}
! CHECK: %[[V_1:[0-9]+]] = fir.alloca !fir.heap<i64> {uniq_name = "_QFssEcount_max.addr"}
! CHECK: %[[V_2:[0-9]+]] = fir.zero_bits !fir.heap<i64>
! CHECK: fir.store %[[V_2]] to %[[V_1]] : !fir.ref<!fir.heap<i64>>
- ! CHECK: %[[V_3:[0-9]+]] = fir.alloca !fir.box<!fir.ptr<i64>> {bindc_name = "count_rate", uniq_name = "_QFssEcount_rate"}
! CHECK: %[[V_4:[0-9]+]] = fir.alloca !fir.ptr<i64> {uniq_name = "_QFssEcount_rate.addr"}
! CHECK: %[[V_5:[0-9]+]] = fir.zero_bits !fir.ptr<i64>
! CHECK: fir.store %[[V_5]] to %[[V_4]] : !fir.ref<!fir.ptr<i64>>
diff --git a/flang/test/Lower/allocatables.f90 b/flang/test/Lower/allocatables.f90
index e62f92f..60b7de3 100644
--- a/flang/test/Lower/allocatables.f90
+++ b/flang/test/Lower/allocatables.f90
@@ -56,7 +56,7 @@ subroutine foodim1()
! CHECK-DAG: fir.load %[[xAddrVar]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
deallocate(x)
- ! CHECK: %[[xAddr1:.*]] = fir.load %1 : !fir.ref<!fir.heap<!fir.array<?xf32>>>
+ ! CHECK: %[[xAddr1:.*]] = fir.load %{{.*}} : !fir.ref<!fir.heap<!fir.array<?xf32>>>
! CHECK: fir.freemem %[[xAddr1]]
! CHECK: %[[nullAddr1:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
! CHECK: fir.store %[[nullAddr1]] to %[[xAddrVar]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
@@ -67,10 +67,6 @@ subroutine foodim2()
! Test lowering of local allocatable specification
real, allocatable :: x(:, :)
! CHECK-DAG: fir.alloca !fir.heap<!fir.array<?x?xf32>> {{{.*}}uniq_name = "_QFfoodim2Ex.addr"}
- ! CHECK-DAG: fir.alloca index {{{.*}}uniq_name = "_QFfoodim2Ex.lb0"}
- ! CHECK-DAG: fir.alloca index {{{.*}}uniq_name = "_QFfoodim2Ex.ext0"}
- ! CHECK-DAG: fir.alloca index {{{.*}}uniq_name = "_QFfoodim2Ex.lb1"}
- ! CHECK-DAG: fir.alloca index {{{.*}}uniq_name = "_QFfoodim2Ex.ext1"}
end subroutine
! test lowering of character allocatables. Focus is placed on the length handling
diff --git a/flang/test/Lower/character-local-variables.f90 b/flang/test/Lower/character-local-variables.f90
index d5b959e..6325229 100644
--- a/flang/test/Lower/character-local-variables.f90
+++ b/flang/test/Lower/character-local-variables.f90
@@ -8,6 +8,7 @@
subroutine scalar_cst_len()
character(10) :: c
! CHECK: fir.alloca !fir.char<1,10> {{{.*}}uniq_name = "_QFscalar_cst_lenEc"}
+ print *, c
end subroutine
! CHECK-LABEL: func @_QPscalar_dyn_len
@@ -19,12 +20,14 @@ subroutine scalar_dyn_len(l)
! CHECK: %[[is_positive:.*]] = arith.cmpi sgt, %[[lexpr]], %c0{{.*}} : i32
! CHECK: %[[l:.*]] = arith.select %[[is_positive]], %[[lexpr]], %c0{{.*}} : i32
! CHECK: fir.alloca !fir.char<1,?>(%[[l]] : i32) {{{.*}}uniq_name = "_QFscalar_dyn_lenEc"}
+ print *, c
end subroutine
! CHECK-LABEL: func @_QPcst_array_cst_len
subroutine cst_array_cst_len()
character(10) :: c(20)
! CHECK: fir.alloca !fir.array<20x!fir.char<1,10>> {{{.*}}uniq_name = "_QFcst_array_cst_lenEc"}
+ print *, c(1)
end subroutine
! CHECK-LABEL: func @_QPcst_array_dyn_len
@@ -36,6 +39,7 @@ subroutine cst_array_dyn_len(l)
! CHECK: %[[is_positive:.*]] = arith.cmpi sgt, %[[lexpr]], %c0{{.*}} : i32
! CHECK: %[[l:.*]] = arith.select %[[is_positive]], %[[lexpr]], %c0{{.*}} : i32
! CHECK: fir.alloca !fir.array<10x!fir.char<1,?>>(%[[l]] : i32) {{{.*}}uniq_name = "_QFcst_array_dyn_lenEc"}
+ print *, c(1)
end subroutine
! CHECK-LABEL: func @_QPdyn_array_cst_len
@@ -48,6 +52,7 @@ subroutine dyn_array_cst_len(n)
! CHECK: %[[is_positive:.*]] = arith.cmpi sgt, %[[ni]], %c0{{.*}} : index
! CHECK: %[[extent:.*]] = arith.select %[[is_positive]], %[[ni]], %c0{{.*}} : index
! CHECK: fir.alloca !fir.array<?x!fir.char<1,10>>, %[[extent]] {{{.*}}uniq_name = "_QFdyn_array_cst_lenEc"}
+ print *, c(1)
end subroutine
! CHECK: func @_QPdyn_array_dyn_len
@@ -63,12 +68,14 @@ subroutine dyn_array_dyn_len(l, n)
! CHECK: %[[is_positive:.*]] = arith.cmpi sgt, %[[ni]], %c0{{.*}} : index
! CHECK: %[[extent:.*]] = arith.select %[[is_positive]], %[[ni]], %c0{{.*}} : index
! CHECK: fir.alloca !fir.array<?x!fir.char<1,?>>(%[[l]] : i32), %[[extent]] {{{.*}}uniq_name = "_QFdyn_array_dyn_lenEc"}
+ print *, c(1)
end subroutine
! CHECK-LABEL: func @_QPcst_array_cst_len_lb
subroutine cst_array_cst_len_lb()
character(10) :: c(11:30)
! CHECK: fir.alloca !fir.array<20x!fir.char<1,10>> {{{.*}}uniq_name = "_QFcst_array_cst_len_lbEc"}
+ print *, c(11)
end subroutine
! CHECK-LABEL: func @_QPcst_array_dyn_len_lb
@@ -80,6 +87,7 @@ subroutine cst_array_dyn_len_lb(l)
! CHECK: %[[is_positive:.*]] = arith.cmpi sgt, %[[lexpr]], %c0{{.*}} : i64
! CHECK: %[[l:.*]] = arith.select %[[is_positive]], %[[lexpr]], %c0{{.*}} : i64
! CHECK: fir.alloca !fir.array<10x!fir.char<1,?>>(%[[l]] : i64) {{{.*}}uniq_name = "_QFcst_array_dyn_len_lbEc"}
+ print *, c(11)
end subroutine
! CHECK-LABEL: func @_QPdyn_array_cst_len_lb
@@ -94,6 +102,7 @@ subroutine dyn_array_cst_len_lb(n)
! CHECK: %[[is_positive:.*]] = arith.cmpi sgt, %[[raw_extent]], %c0{{.*}} : index
! CHECK: %[[extent:.*]] = arith.select %[[is_positive]], %[[raw_extent]], %c0{{.*}} : index
! CHECK: fir.alloca !fir.array<?x!fir.char<1,10>>, %[[extent]] {{{.*}}uniq_name = "_QFdyn_array_cst_len_lbEc"}
+ print *, c(11)
end subroutine
! CHECK-LABEL: func @_QPdyn_array_dyn_len_lb
@@ -111,6 +120,7 @@ subroutine dyn_array_dyn_len_lb(l, n)
! CHECK: %[[is_positive:.*]] = arith.cmpi sgt, %[[raw_extent]], %c0{{.*}} : index
! CHECK: %[[extent:.*]] = arith.select %[[is_positive]], %[[raw_extent]], %c0{{.*}} : index
! CHECK: fir.alloca !fir.array<?x!fir.char<1,?>>(%[[l]] : i64), %[[extent]] {{{.*}}uniq_name = "_QFdyn_array_dyn_len_lbEc"}
+ print *, c(11)
end subroutine
! Test that the length of assumed length parameter is correctly deduced in lowering.
@@ -129,4 +139,5 @@ end
subroutine scalar_cst_neg_len()
character(-1) :: c
! CHECK: fir.alloca !fir.char<1,0> {{{.*}}uniq_name = "_QFscalar_cst_neg_lenEc"}
+ print *, c
end subroutine
diff --git a/flang/test/Lower/derived-types.f90 b/flang/test/Lower/derived-types.f90
index 4d36a76..7e36ec0 100644
--- a/flang/test/Lower/derived-types.f90
+++ b/flang/test/Lower/derived-types.f90
@@ -35,6 +35,8 @@ subroutine local_derived()
! CHECK-DAG: fir.alloca !fir.type<_QMdTr{x:f32}>
type(r) :: some_r
type(c2) :: some_c2
+ print *, some_c2%ch_array(1,1)
+ print *, some_r%x
end subroutine
! CHECK-LABEL: func @_QMdPsaved_derived(
diff --git a/flang/test/Lower/do_loop_unstructured.f90 b/flang/test/Lower/do_loop_unstructured.f90
index 3b03850..9c7d874 100644
--- a/flang/test/Lower/do_loop_unstructured.f90
+++ b/flang/test/Lower/do_loop_unstructured.f90
@@ -235,6 +235,7 @@ end subroutine
subroutine unstructured_do_concurrent
logical :: success
do concurrent (i=1:10) local(success)
+ success = .false.
error stop "fail"
enddo
end
diff --git a/flang/test/Lower/forall/array-pointer.f90 b/flang/test/Lower/forall/array-pointer.f90
index fd3efed..6b8c564 100644
--- a/flang/test/Lower/forall/array-pointer.f90
+++ b/flang/test/Lower/forall/array-pointer.f90
@@ -318,7 +318,6 @@ end subroutine s2_3
! CHECK-LABEL: func @_QPs2_3(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
-! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "y", fir.target, uniq_name = "_QFs2_3Ey"}
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.heap<!fir.array<?xi32>> {uniq_name = "_QFs2_3Ey.addr"}
! CHECK: %[[VAL_4:.*]] = fir.alloca index {uniq_name = "_QFs2_3Ey.lb0"}
! CHECK: %[[VAL_5:.*]] = fir.alloca index {uniq_name = "_QFs2_3Ey.ext0"}
diff --git a/flang/test/Lower/forall/forall-allocatable.f90 b/flang/test/Lower/forall/forall-allocatable.f90
index 96cd37e..8e54d28 100644
--- a/flang/test/Lower/forall/forall-allocatable.f90
+++ b/flang/test/Lower/forall/forall-allocatable.f90
@@ -13,20 +13,19 @@ end subroutine forall_with_allocatable
! CHECK-LABEL: func @_QPforall_with_allocatable(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
-! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "arr", uniq_name = "_QFforall_with_allocatableEarr"}
-! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.heap<!fir.array<?xf32>> {uniq_name = "_QFforall_with_allocatableEarr.addr"}
-! CHECK: %[[VAL_4:.*]] = fir.alloca index {uniq_name = "_QFforall_with_allocatableEarr.lb0"}
-! CHECK: %[[VAL_5:.*]] = fir.alloca index {uniq_name = "_QFforall_with_allocatableEarr.ext0"}
-! CHECK: %[[VAL_6:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
-! CHECK: fir.store %[[VAL_6]] to %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
+! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.heap<!fir.array<?xf32>> {uniq_name = "_QFforall_with_allocatableEarr.addr"}
+! CHECK: %[[VAL_3:.*]] = fir.alloca index {uniq_name = "_QFforall_with_allocatableEarr.lb0"}
+! CHECK: %[[VAL_4:.*]] = fir.alloca index {uniq_name = "_QFforall_with_allocatableEarr.ext0"}
+! CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+! CHECK: fir.store %[[VAL_5]] to %[[VAL_2]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
! CHECK: %[[VAL_7:.*]] = arith.constant 5 : i32
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index
! CHECK: %[[VAL_9:.*]] = arith.constant 15 : i32
! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
! CHECK: %[[VAL_11:.*]] = arith.constant 1 : index
-! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_4]] : !fir.ref<index>
-! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_5]] : !fir.ref<index>
-! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
+! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_3]] : !fir.ref<index>
+! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_4]] : !fir.ref<index>
+! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.heap<!fir.array<?xf32>>>
! CHECK: %[[VAL_15:.*]] = fir.shape_shift %[[VAL_12]], %[[VAL_13]] : (index, index) -> !fir.shapeshift<1>
! CHECK: %[[VAL_16:.*]] = fir.array_load %[[VAL_14]](%[[VAL_15]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.array<?xf32>
! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>
diff --git a/flang/test/Lower/loops.f90 b/flang/test/Lower/loops.f90
index 2fea84b..5ee6562 100644
--- a/flang/test/Lower/loops.f90
+++ b/flang/test/Lower/loops.f90
@@ -90,7 +90,6 @@ subroutine lis(n)
! CHECK-DAG: fir.alloca !fir.array<?x?x?xi32>, %{{.*}}, %{{.*}}, %{{.*}} {bindc_name = "a", fir.target, uniq_name = "_QFlisEa"}
! CHECK-DAG: fir.alloca !fir.array<?x?xi32>, %{{.*}}, %{{.*}} {bindc_name = "r", uniq_name = "_QFlisEr"}
! CHECK-DAG: fir.alloca !fir.array<?x?xi32>, %{{.*}}, %{{.*}} {bindc_name = "s", uniq_name = "_QFlisEs"}
- ! CHECK-DAG: fir.alloca !fir.array<?x?xi32>, %{{.*}}, %{{.*}} {bindc_name = "t", uniq_name = "_QFlisEt"}
integer, target :: a(n,n,n) ! operand via p
integer :: r(n,n) ! result, unspecified locality
integer :: s(n,n) ! shared locality
diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90
index f586380..bc4eed5 100644
--- a/flang/test/Lower/polymorphic.f90
+++ b/flang/test/Lower/polymorphic.f90
@@ -287,7 +287,6 @@ module polymorphic_test
! First test is here to have a reference with non polymorphic on both sides.
! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_parent(
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp2{a:i32,b:i32,c:f32}>> {fir.bindc_name = "p", fir.target}) {
-! CHECK: %[[TP:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {bindc_name = "tp", uniq_name = "_QMpolymorphic_testFpointer_assign_parentEtp"}
! CHECK: %[[PTR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {uniq_name = "_QMpolymorphic_testFpointer_assign_parentEtp.addr"}
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
! CHECK: fir.store %[[ZERO]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
@@ -302,7 +301,6 @@ module polymorphic_test
! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_non_poly(
! CHECK-SAME: %arg0: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "p", fir.target}) {
-! CHECK: %[[TP:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {bindc_name = "tp", uniq_name = "_QMpolymorphic_testFpointer_assign_non_polyEtp"}
! CHECK: %[[PTR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {uniq_name = "_QMpolymorphic_testFpointer_assign_non_polyEtp.addr"}
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
! CHECK: fir.store %[[ZERO]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
@@ -1103,11 +1101,9 @@ module polymorphic_test
! CHECK-LABEL: func.func @_QMpolymorphic_testPclass_with_entry(
! CHECK-SAME: %[[A:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}) {
-! CHECK: %[[B:.*]] = fir.alloca !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {bindc_name = "b", uniq_name = "_QMpolymorphic_testFclass_with_entryEb"}
! CHECK-LABEL: func.func @_QMpolymorphic_testPd(
! CHECK-SAME: %[[B:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "b"}) {
-! CHECK: %[[A:.*]] = fir.alloca !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {bindc_name = "a", uniq_name = "_QMpolymorphic_testFclass_with_entryEa"}
subroutine class_array_with_entry(a)
class(p1) :: a(:), b(:)
diff --git a/flang/test/Lower/statement-function.f90 b/flang/test/Lower/statement-function.f90
index cfec06c..fe07649 100644
--- a/flang/test/Lower/statement-function.f90
+++ b/flang/test/Lower/statement-function.f90
@@ -129,7 +129,6 @@ integer function test_stmt_character_with_different_length_2(c, n)
character(n) :: argc
character(*) :: c
! CHECK: %[[unboxed:.*]]:2 = fir.unboxchar %[[arg0]] :
- ! CHECK: fir.load %[[arg1]] : !fir.ref<i32>
! CHECK: %[[n:.*]] = fir.load %[[arg1]] : !fir.ref<i32>
! CHECK: %[[n_is_positive:.*]] = arith.cmpi sgt, %[[n]], %c0{{.*}} : i32
! CHECK: %[[len:.*]] = arith.select %[[n_is_positive]], %[[n]], %c0{{.*}} : i32
diff --git a/flang/test/Transforms/stack-arrays.fir b/flang/test/Transforms/stack-arrays.fir
index 4a417ed..25fc731 100644
--- a/flang/test/Transforms/stack-arrays.fir
+++ b/flang/test/Transforms/stack-arrays.fir
@@ -3,13 +3,17 @@
// Simplest transformation
func.func @simple() {
%0 = fir.allocmem !fir.array<42xi32>
+ %c0_s = arith.constant 0 : index
+ %c0_i32_s = arith.constant 0 : i32
+ %ref_s = fir.convert %0 : (!fir.heap<!fir.array<42xi32>>) -> !fir.ref<!fir.array<42xi32>>
+ %elt_s = fir.coordinate_of %ref_s, %c0_s : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32_s to %elt_s : !fir.ref<i32>
fir.freemem %0 : !fir.heap<!fir.array<42xi32>>
return
}
-// CHECK: func.func @simple() {
-// CHECK-NEXT: fir.alloca !fir.array<42xi32>
-// CHECK-NEXT: return
-// CHECK-NEXT: }
+// CHECK: func.func @simple()
+// CHECK: fir.alloca !fir.array<42xi32>
+// CHECK: return
// Check fir.must_be_heap allocations are not moved
func.func @must_be_heap() {
@@ -17,7 +21,7 @@ func.func @must_be_heap() {
fir.freemem %0 : !fir.heap<!fir.array<42xi32>>
return
}
-// CHECK: func.func @must_be_heap() {
+// CHECK-LABEL: func.func @must_be_heap()
// CHECK-NEXT: %[[ALLOC:.*]] = fir.allocmem !fir.array<42xi32> {fir.must_be_heap = true}
// CHECK-NEXT: fir.freemem %[[ALLOC]] : !fir.heap<!fir.array<42xi32>>
// CHECK-NEXT: return
@@ -36,7 +40,7 @@ func.func @dfa1(%arg0: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
}
return
}
-// CHECK: func.func @dfa1(%arg0: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"}) {
+// CHECK-LABEL: func.func @dfa1(%arg0: !fir.ref<!fir.logical<4>> {fir.bindc_name = "cond"})
// CHECK-NEXT: %[[C42:.*]] = arith.constant 42 : index
// CHECK-NEXT: %[[MEM:.*]] = fir.allocmem !fir.array<?xi32>, %[[C42]] {uniq_name = "_QFdfa1Earr.alloc"}
// CHECK-NEXT: %[[LOGICAL:.*]] = fir.load %arg0 : !fir.ref<!fir.logical<4>>
@@ -57,7 +61,7 @@ func.func @dfa2(%arg0: i1) {
}
return
}
-// CHECK: func.func @dfa2(%arg0: i1) {
+// CHECK-LABEL: func.func @dfa2(%arg0: i1)
// CHECK-NEXT: %[[MEM:.*]] = fir.allocmem !fir.array<1xi8>
// CHECK-NEXT: scf.if %arg0 {
// CHECK-NEXT: fir.freemem %[[MEM]] : !fir.heap<!fir.array<1xi8>>
@@ -74,15 +78,16 @@ func.func @dfa3(%arg0: i1) {
} else {
fir.freemem %a : !fir.heap<!fir.array<1xi8>>
}
+ %c0_d3 = arith.constant 0 : index
+ %c0_i8_d3 = arith.constant 0 : i8
+ %ref_d3 = fir.convert %a : (!fir.heap<!fir.array<1xi8>>) -> !fir.ref<!fir.array<1xi8>>
+ %elt_d3 = fir.coordinate_of %ref_d3, %c0_d3 : (!fir.ref<!fir.array<1xi8>>, index) -> !fir.ref<i8>
+ fir.store %c0_i8_d3 to %elt_d3 : !fir.ref<i8>
return
}
-// CHECK: func.func @dfa3(%arg0: i1) {
-// CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<1xi8>
-// CHECK-NEXT: fir.if %arg0 {
-// CHECK-NEXT: } else {
-// CHECK-NEXT: }
-// CHECK-NEXT: return
-// CHECK-NEXT: }
+// CHECK: func.func @dfa3(%arg0: i1)
+// CHECK: %[[MEM:.*]] = fir.alloca !fir.array<1xi8>
+// CHECK: return
func.func private @dfa3a_foo(!fir.ref<!fir.array<1xi8>>) -> ()
func.func private @dfa3a_bar(!fir.ref<!fir.array<1xi8>>) -> ()
@@ -101,7 +106,7 @@ func.func @dfa3a(%arg0: i1) {
}
return
}
-// CHECK: func.func @dfa3a(%arg0: i1) {
+// CHECK-LABEL: func.func @dfa3a(%arg0: i1)
// CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<1xi8>
// CHECK-NEXT: %[[HEAP:.*]] = fir.convert %[[MEM]] : (!fir.ref<!fir.array<1xi8>>) -> !fir.heap<!fir.array<1xi8>>
// CHECK-NEXT: fir.if %arg0 {
@@ -123,13 +128,18 @@ func.func @placement1() {
// operand is now available
%4 = fir.allocmem !fir.array<?xi32>, %3
// ...
+ %c0 = arith.constant 0 : index
+ %c0_i32 = arith.constant 0 : i32
+ %ref1 = fir.convert %4 : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+ %elt1 = fir.coordinate_of %ref1, %c0 : (!fir.ref<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32 to %elt1 : !fir.ref<i32>
fir.freemem %4 : !fir.heap<!fir.array<?xi32>>
return
}
-// CHECK: func.func @placement1() {
+// CHECK-LABEL: func.func @placement1()
// CHECK-NEXT: %[[ARG:.*]] = arith.constant 3 : index
// CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<?xi32>, %[[ARG]]
-// CHECK-NEXT: return
+// CHECK: return
// CHECK-NEXT: }
// check that if there are no operands, then the alloca is placed early
@@ -140,16 +150,21 @@ func.func @placement2() {
%3 = arith.addi %1, %2 : index
%4 = fir.allocmem !fir.array<42xi32>
// ...
+ %c0_p2 = arith.constant 0 : index
+ %c0_i32_p2 = arith.constant 0 : i32
+ %ref_p2 = fir.convert %4 : (!fir.heap<!fir.array<42xi32>>) -> !fir.ref<!fir.array<42xi32>>
+ %elt_p2 = fir.coordinate_of %ref_p2, %c0_p2 : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32_p2 to %elt_p2 : !fir.ref<i32>
fir.freemem %4 : !fir.heap<!fir.array<42xi32>>
return
}
-// CHECK: func.func @placement2() {
-// CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<42xi32>
-// CHECK-NEXT: %[[ONE:.*]] = arith.constant 1 : index
-// CHECK-NEXT: %[[TWO:.*]] = arith.constant 2 : index
-// CHECK-NEXT: %[[SUM:.*]] = arith.addi %[[ONE]], %[[TWO]] : index
-// CHECK-NEXT: return
-// CHECK-NEXT: }
+// CHECK-LABEL: func.func @placement2()
+// CHECK: %[[MEM:.*]] = fir.alloca !fir.array<42xi32>
+// CHECK: %[[ONE:.*]] = arith.constant 1 : index
+// CHECK: %[[TWO:.*]] = arith.constant 2 : index
+// CHECK: %[[SUM:.*]] = arith.addi %[[ONE]], %[[TWO]] : index
+// CHECK: return
+// CHECK: }
// check that stack allocations which must be placed in loops use stacksave
func.func @placement3() {
@@ -162,12 +177,17 @@ func.func @placement3() {
// operand is now available
%4 = fir.allocmem !fir.array<?xi32>, %3
// ...
+ %c0 = arith.constant 0 : index
+ %c0_i32 = arith.constant 0 : i32
+ %ref2 = fir.convert %4 : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+ %elt2 = fir.coordinate_of %ref2, %c0 : (!fir.ref<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32 to %elt2 : !fir.ref<i32>
fir.freemem %4 : !fir.heap<!fir.array<?xi32>>
fir.result %3, %c1_i32 : index, i32
}
return
}
-// CHECK: func.func @placement3() {
+// CHECK-LABEL: func.func @placement3()
// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index
// CHECK-NEXT: %[[C1_I32:.*]] = fir.convert %[[C1]] : (index) -> i32
// CHECK-NEXT: %[[C2:.*]] = arith.constant 2 : index
@@ -176,7 +196,7 @@ func.func @placement3() {
// CHECK-NEXT: %[[SUM:.*]] = arith.addi %[[C1]], %[[C2]] : index
// CHECK-NEXT: %[[SP:.*]] = llvm.intr.stacksave : !llvm.ptr
// CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<?xi32>, %[[SUM]]
-// CHECK-NEXT: llvm.intr.stackrestore %[[SP]] : !llvm.ptr
+// CHECK: llvm.intr.stackrestore %[[SP]] : !llvm.ptr
// CHECK-NEXT: fir.result
// CHECK-NEXT: }
// CHECK-NEXT: return
@@ -194,12 +214,17 @@ func.func @placement4(%arg0 : i1) {
// operand is now available
%4 = fir.allocmem !fir.array<?xi32>, %3
// ...
+ %c0 = arith.constant 0 : index
+ %c0_i32 = arith.constant 0 : i32
+ %ref3 = fir.convert %4 : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+ %elt3 = fir.coordinate_of %ref3, %c0 : (!fir.ref<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32 to %elt3 : !fir.ref<i32>
fir.freemem %4 : !fir.heap<!fir.array<?xi32>>
cf.cond_br %arg0, ^bb1, ^bb2
^bb2:
return
}
-// CHECK: func.func @placement4(%arg0: i1) {
+// CHECK-LABEL: func.func @placement4(%arg0: i1)
// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index
// CHECK-NEXT: %[[C1_I32:.*]] = fir.convert %[[C1]] : (index) -> i32
// CHECK-NEXT: %[[C10:.*]] = arith.constant 10 : index
@@ -208,7 +233,7 @@ func.func @placement4(%arg0 : i1) {
// CHECK-NEXT: %[[C3:.*]] = arith.constant 3 : index
// CHECK-NEXT: %[[SP:.*]] = llvm.intr.stacksave : !llvm.ptr
// CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<?xi32>, %[[C3]]
-// CHECK-NEXT: llvm.intr.stackrestore %[[SP]] : !llvm.ptr
+// CHECK: llvm.intr.stackrestore %[[SP]] : !llvm.ptr
// CHECK-NEXT: cf.cond_br %arg0, ^bb1, ^bb2
// CHECK-NEXT: ^bb2:
// CHECK-NEXT: return
@@ -230,7 +255,7 @@ func.func @placement5() {
}
return
}
-// CHECK: func.func @placement5() {
+// CHECK-LABEL: func.func @placement5()
// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index
// CHECK-NEXT: %[[C1_I32:.*]] = fir.convert %[[C1]] : (index) -> i32
// CHECK-NEXT: %[[C2:.*]] = arith.constant 2 : index
@@ -268,7 +293,7 @@ func.func @placement6(%arg0: i1) {
fir.freemem %4 : !fir.heap<!fir.array<?xi32>>
cf.br ^bb1
}
-// CHECK: func.func @placement6(%arg0: i1) {
+// CHECK-LABEL: func.func @placement6(%arg0: i1)
// CHECK-NEXT: %[[c1:.*]] = arith.constant 1 : index
// CHECK-NEXT: %[[c1_i32:.*]] = fir.convert %[[c1]] : (index) -> i32
// CHECK-NEXT: %[[c2:.*]] = arith.constant 2 : index
@@ -289,6 +314,11 @@ func.func @placement6(%arg0: i1) {
// Check multiple returns, where the memory is always freed
func.func @returns(%arg0: i1) {
%0 = fir.allocmem !fir.array<42xi32>
+ %c0_ret = arith.constant 0 : index
+ %c0_i32_ret = arith.constant 0 : i32
+ %ref_ret = fir.convert %0 : (!fir.heap<!fir.array<42xi32>>) -> !fir.ref<!fir.array<42xi32>>
+ %elt_ret = fir.coordinate_of %ref_ret, %c0_ret : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32_ret to %elt_ret : !fir.ref<i32>
cf.cond_br %arg0, ^bb1, ^bb2
^bb1:
fir.freemem %0 : !fir.heap<!fir.array<42xi32>>
@@ -297,9 +327,9 @@ func.func @returns(%arg0: i1) {
fir.freemem %0 : !fir.heap<!fir.array<42xi32>>
return
}
-// CHECK: func.func @returns(%[[COND:.*]]: i1) {
-// CHECK-NEXT: %[[ALLOC:.*]] = fir.alloca !fir.array<42xi32>
-// CHECK-NEXT: cf.cond_br %[[COND]], ^bb1, ^bb2
+// CHECK-LABEL: func.func @returns(
+// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.array<42xi32>
+// CHECK: cf.cond_br %{{.*}}, ^bb1, ^bb2
// CHECK-NEXT: ^bb1:
// CHECK-NEXT: return
// CHECK-NEXT: ^bb2:
@@ -309,6 +339,11 @@ func.func @returns(%arg0: i1) {
// Check multiple returns, where the memory is not freed on one branch
func.func @returns2(%arg0: i1) {
%0 = fir.allocmem !fir.array<42xi32>
+ %c0_ret2 = arith.constant 0 : index
+ %c0_i32_ret2 = arith.constant 0 : i32
+ %ref_ret2 = fir.convert %0 : (!fir.heap<!fir.array<42xi32>>) -> !fir.ref<!fir.array<42xi32>>
+ %elt_ret2 = fir.coordinate_of %ref_ret2, %c0_ret2 : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32_ret2 to %elt_ret2 : !fir.ref<i32>
cf.cond_br %arg0, ^bb1, ^bb2
^bb1:
fir.freemem %0 : !fir.heap<!fir.array<42xi32>>
@@ -316,9 +351,9 @@ func.func @returns2(%arg0: i1) {
^bb2:
return
}
-// CHECK: func.func @returns2(%[[COND:.*]]: i1) {
-// CHECK-NEXT: %[[ALLOC:.*]] = fir.allocmem !fir.array<42xi32>
-// CHECK-NEXT: cf.cond_br %[[COND]], ^bb1, ^bb2
+// CHECK-LABEL: func.func @returns2(
+// CHECK: %[[ALLOC:.*]] = fir.allocmem !fir.array<42xi32>
+// CHECK: cf.cond_br %{{.*}}, ^bb1, ^bb2
// CHECK-NEXT: ^bb1:
// CHECK-NEXT: fir.freemem %[[ALLOC]] : !fir.heap<!fir.array<42xi32>>
// CHECK-NEXT: return
@@ -338,7 +373,7 @@ func.func @omp_placement1() {
}
return
}
-// CHECK: func.func @omp_placement1() {
+// CHECK-LABEL: func.func @omp_placement1()
// CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<42xi32>
// CHECK-NEXT: %[[MEM_CONV:.*]] = fir.convert %[[MEM]] : (!fir.ref<!fir.array<42xi32>>) -> !fir.heap<!fir.array<42xi32>>
// CHECK-NEXT: omp.sections {
@@ -353,19 +388,21 @@ func.func @omp_placement1() {
// function terminated by stop statement
func.func @stop_terminator() {
%0 = fir.allocmem !fir.array<42xi32>
+ %c0 = arith.constant 0 : index
+ %c0_i32_st = arith.constant 0 : i32
+ %ref4 = fir.convert %0 : (!fir.heap<!fir.array<42xi32>>) -> !fir.ref<!fir.array<42xi32>>
+ %elt4 = fir.coordinate_of %ref4, %c0 : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
+ fir.store %c0_i32_st to %elt4 : !fir.ref<i32>
fir.freemem %0 : !fir.heap<!fir.array<42xi32>>
%c0_i32 = arith.constant 0 : i32
%false = arith.constant false
fir.call @_FortranAStopStatement(%c0_i32, %false, %false) : (i32, i1, i1) -> ()
fir.unreachable
}
-// CHECK: func.func @stop_terminator() {
-// CHECK-NEXT: fir.alloca !fir.array<42xi32>
-// CHECK-NEXT: %[[ZERO:.*]] = arith.constant 0 : i32
-// CHECK-NEXT: %[[FALSE:.*]] = arith.constant false
-// CHECK-NEXT: fir.call @_FortranAStopStatement(%[[ZERO]], %[[FALSE]], %[[FALSE]]) : (i32, i1, i1) -> ()
-// CHECK-NEXT: fir.unreachable
-// CHECK-NEXT: }
+// CHECK-LABEL: func.func @stop_terminator()
+// CHECK: fir.alloca !fir.array<42xi32>
+// CHECK: fir.call @_FortranAStopStatement(
+// CHECK: fir.unreachable
// check that stack allocations that use fir.declare which must be placed in loops
@@ -387,7 +424,7 @@ func.func @placement_loop_declare() {
}
return
}
-// CHECK: func.func @placement_loop_declare() {
+// CHECK-LABEL: func.func @placement_loop_declare()
// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index
// CHECK-NEXT: %[[C1_I32:.*]] = fir.convert %[[C1]] : (index) -> i32
// CHECK-NEXT: %[[C2:.*]] = arith.constant 2 : index
@@ -415,7 +452,7 @@ func.func @lookthrough() {
fir.freemem %4 : !fir.heap<!fir.array<42xi32>>
return
}
-// CHECK: func.func @lookthrough() {
+// CHECK-LABEL: func.func @lookthrough()
// CHECK: fir.alloca !fir.array<42xi32>
// CHECK-NOT: fir.freemem
@@ -457,6 +494,6 @@ func.func @finding_freemem_in_block() {
^bb3: // pred: ^bb1
return
}
-// CHECK: func.func @finding_freemem_in_block() {
+// CHECK-LABEL: func.func @finding_freemem_in_block()
// CHECK: fir.alloca !fir.array<?xi32>
// CHECK-NOT: fir.freemem