[all-commits] [llvm/llvm-project] 73026a: [flang] Changed lowering for allocatable assignmen...
Slava Zakharin via All-commits
all-commits at lists.llvm.org
Fri Jul 8 09:47:50 PDT 2022
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 73026a4fbf7095613df4f8c205912cfc1485ed7d
https://github.com/llvm/llvm-project/commit/73026a4fbf7095613df4f8c205912cfc1485ed7d
Author: Slava Zakharin <szakharin at nvidia.com>
Date: 2022-07-08 (Fri, 08 Jul 2022)
Changed paths:
M flang/include/flang/Optimizer/Builder/MutableBox.h
M flang/lib/Lower/ConvertExpr.cpp
M flang/lib/Optimizer/Builder/MutableBox.cpp
M flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp
M flang/test/Lower/allocatable-assignment.f90
Log Message:
-----------
[flang] Changed lowering for allocatable assignment to make array-value-copy correct.
Array-value-copy fails to generate a temporary array for case like this:
subroutine bug(b)
real, allocatable :: b(:)
b = b(2:1:-1)
end subroutine
Since LHS may need to be reallocated, lowering produces the following FIR:
%rhs_load = fir.array_load %b %slice
%lhs_mem = fir.if %b_is_allocated_with_right_shape {
fir.result %b
} else {
%new_storage = fir.allocmem %rhs_shape
fir.result %new_storage
}
%lhs = fir.array_load %lhs_mem
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %lhs_mem
// deallocate old storage if reallocation occured,
// and update b descriptor if needed.
Since %b in array_load and %lhs_mem in array_merge_store are not the same SSA
values, array-value-copy does not detect the conflict and does not produce
a temporary array. This causes incorrect result in runtime.
The suggested change in lowering is to generate this:
%rhs_load = fir.array_load %b %slice
%lhs_mem = fir.if %b_is_allocated_with_right_shape {
%lhs = fir.array_load %b
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %b
fir.result %b
} else {
%new_storage = fir.allocmem %rhs_shape
%lhs = fir.array_load %new_storage
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %new_storage
fir.result %new_storage
}
// deallocate old storage if reallocation occured,
// and update b descriptor if needed.
Note that there are actually 3 branches in FIR, so the assignment loops
are currently produced in three copies, which is a code-size issue.
It is possible to generate just two branches with two copies of the loops,
but it is not addressed in this change-set.
Differential Revision: https://reviews.llvm.org/D129314
More information about the All-commits
mailing list