[flang-commits] [flang] 1ee9080 - [flang] Preserve bound info for pointer assignments through derived types
Jonathon Penix via flang-commits
flang-commits at lists.llvm.org
Mon Dec 12 14:28:30 PST 2022
Author: Jonathon Penix
Date: 2022-12-12T14:22:22-08:00
New Revision: 1ee9080d6b94e1779ba9f0078c9d570d14ca7e35
URL: https://github.com/llvm/llvm-project/commit/1ee9080d6b94e1779ba9f0078c9d570d14ca7e35
DIFF: https://github.com/llvm/llvm-project/commit/1ee9080d6b94e1779ba9f0078c9d570d14ca7e35.diff
LOG: [flang] Preserve bound info for pointer assignments through derived types
Doing a pointer assignment to another pointer which is a derived type component
could result in the bound information being lost, potentially leading to
incorrect array accesses. Fix this by trying to retain the bound info during
the assignment.
Fixes #57441
Differential Revision: https://reviews.llvm.org/D139800
Added:
Modified:
flang/lib/Lower/ConvertExpr.cpp
flang/test/Lower/parent-component.f90
flang/test/Lower/pointer-assignments.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index 93aec925bbe6f..0378da27d736d 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -5639,6 +5639,13 @@ class ArrayExprLowering {
builder.getContext(), charTy.getFKind()),
seqTy.getDimension()));
}
+ llvm::SmallVector<mlir::Value> lbounds;
+ llvm::SmallVector<mlir::Value> nonDeferredLenParams;
+ if (!slice) {
+ lbounds =
+ fir::factory::getNonDefaultLowerBounds(builder, loc, extMemref);
+ nonDeferredLenParams = fir::factory::getNonDeferredLenParams(extMemref);
+ }
mlir::Value embox =
memref.getType().isa<fir::BaseBoxType>()
? builder.create<fir::ReboxOp>(loc, boxTy, memref, shape, slice)
@@ -5647,7 +5654,9 @@ class ArrayExprLowering {
.create<fir::EmboxOp>(loc, boxTy, memref, shape, slice,
fir::getTypeParams(extMemref))
.getResult();
- return [=](IterSpace) -> ExtValue { return fir::BoxValue(embox); };
+ return [=](IterSpace) -> ExtValue {
+ return fir::BoxValue(embox, lbounds, nonDeferredLenParams);
+ };
}
auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
if (isReferentiallyOpaque()) {
diff --git a/flang/test/Lower/parent-component.f90 b/flang/test/Lower/parent-component.f90
index babfc7cc9f723..ea7e7744000e8 100644
--- a/flang/test/Lower/parent-component.f90
+++ b/flang/test/Lower/parent-component.f90
@@ -135,7 +135,9 @@ subroutine init_allocatable()
! CHECK: %[[C0:.*]] = arith.constant 0 : index
! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %{{.*}}, %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QFTc{a:i32,b:i32}>>>, index) -> (index, index, index)
! CHECK: %[[C1:.*]] = arith.constant 1 : index
- ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1>
+ ! CHECK: %[[BOUND_OFFSET:.*]] = arith.subi %[[LOAD_LB0]], %[[C1]] : index
+ ! CHECK: %[[UB:.*]] = arith.addi %[[BOX_DIMS]]#1, %[[BOUND_OFFSET]] : index
+ ! CHECK: %[[SLICE:.*]] = fir.slice %[[LOAD_LB0]], %[[UB]], %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1>
! CHECK: %[[BOX:.*]] = fir.embox %[[MEM]](%[[SHAPE_SHIFT]]) [%[[SLICE]]] : (!fir.heap<!fir.array<?x!fir.type<_QFTc{a:i32,b:i32}>>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?x!fir.type<_QFTp{a:i32}>>>
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box<!fir.array<?x!fir.type<_QFTp{a:i32}>>>) -> !fir.box<none>
! CHECK: %[[IS_CONTIGOUS:.*]] = fir.call @_FortranAIsContiguous(%[[BOX_NONE]]) {{.*}}: (!fir.box<none>) -> i1
@@ -156,7 +158,9 @@ subroutine init_allocatable()
! CHECK: %[[C0:.*]] = arith.constant 0 : index
! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %{{.*}}, %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QFTc{a:i32,b:i32}>>>, index) -> (index, index, index)
! CHECK: %[[C1:.*]] = arith.constant 1 : index
- ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1>
+ ! CHECK: %[[BOUND_OFFSET:.*]] = arith.subi %[[LOAD_LB0]], %[[C1]] : index
+ ! CHECK: %[[UB:.*]] = arith.addi %[[BOX_DIMS]]#1, %[[BOUND_OFFSET]] : index
+ ! CHECK: %[[SLICE:.*]] = fir.slice %[[LOAD_LB0]], %[[UB]], %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1>
! CHECK: %[[BOX:.*]] = fir.embox %[[LOAD_ALLOC]](%[[SHAPE_SHIFT]]) [%[[SLICE]]] : (!fir.heap<!fir.array<?x!fir.type<_QFTc{a:i32,b:i32}>>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?x!fir.type<_QFTp{a:i32}>>>
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box<!fir.array<?x!fir.type<_QFTp{a:i32}>>>) -> !fir.box<none>
! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) {{.*}}: (!fir.ref<i8>, !fir.box<none>) -> i1
diff --git a/flang/test/Lower/pointer-assignments.f90 b/flang/test/Lower/pointer-assignments.f90
index 0f3feff3add96..d4e63435b1983 100644
--- a/flang/test/Lower/pointer-assignments.f90
+++ b/flang/test/Lower/pointer-assignments.f90
@@ -67,6 +67,26 @@ subroutine test_array_with_lbs(p, x)
p => x
end subroutine
+! Test that the lhs takes the bounds from rhs.
+! CHECK-LABEL: func @_QPtest_pointer_component(
+! CHECK-SAME: %[[temp:.*]]: !fir.ref<!fir.type<_QFtest_pointer_componentTmytype{ptr:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> {fir.bindc_name = "temp"}, %[[temp_ptr:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {fir.bindc_name = "temp_ptr"}) {
+subroutine test_pointer_component(temp, temp_ptr)
+ type mytype
+ real, pointer :: ptr(:)
+ end type mytype
+ type(mytype) :: temp
+ real, pointer :: temp_ptr(:)
+ ! CHECK: %[[ptr_addr:.*]] = fir.coordinate_of %[[temp]], %{{.*}} : (!fir.ref<!fir.type<_QFtest_pointer_componentTmytype{ptr:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ ! CHECK: %[[ptr:.*]] = fir.load %[[ptr_addr]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[ptr]], %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
+ ! CHECK: %[[shift:.*]] = fir.shift %[[dims]]#0 : (index) -> !fir.shift<1>
+ ! CHECK: %[[arr_box:.*]] = fir.rebox %[[ptr]](%[[shift]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.array<?xf32>>
+ ! CHECK: %[[shift2:.*]] = fir.shift %[[dims]]#0 : (index) -> !fir.shift<1>
+ ! CHECK: %[[final_box:.*]] = fir.rebox %[[arr_box]](%[[shift2]]) : (!fir.box<!fir.array<?xf32>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: fir.store %[[final_box]] to %[[temp_ptr]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ temp_ptr => temp%ptr
+end subroutine
+
! -----------------------------------------------------------------------------
! Test pointer assignments with bound specs to contiguous right-hand side
! -----------------------------------------------------------------------------
More information about the flang-commits
mailing list