mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-28 16:11:29 +00:00
[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
This commit is contained in:
parent
6ab01d4a5c
commit
1ee9080d6b
@ -5639,6 +5639,13 @@ private:
|
||||
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 @@ private:
|
||||
.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()) {
|
||||
|
@ -135,7 +135,9 @@ contains
|
||||
! 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 @@ contains
|
||||
! 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
|
||||
|
@ -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
|
||||
! -----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user