llvm-project/flang/lib
Slava Zakharin 73026a4fbf [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
2022-07-08 09:41:34 -07:00
..
Common [flang] Use the Flang cmake-functions to add targets. 2020-04-16 15:51:30 +01:00
Decimal [flang][runtime] Use __float128 where possible & needed in runtime 2022-06-05 09:16:57 -07:00
Evaluate [flang] Add IsElementalProcedure() predicate 2022-07-06 18:08:45 -07:00
Frontend [flang] Establish a single source of target information for semantics 2022-07-06 10:25:34 -07:00
FrontendTool [flang][Driver] Refine _when_ driver diagnostics are formatted 2022-06-22 23:56:34 +08:00
Lower [flang] Changed lowering for allocatable assignment to make array-value-copy correct. 2022-07-08 09:41:34 -07:00
Optimizer [flang] Changed lowering for allocatable assignment to make array-value-copy correct. 2022-07-08 09:41:34 -07:00
Parser [flang][openacc][NFC] Extract device_type parser to its own 2022-07-08 16:02:04 +02:00
Semantics [flang][openacc][NFC] Make self clause value optional in ACC.td and extract the parser 2022-07-08 15:45:12 +02:00
CMakeLists.txt [flang][driver] Delete `f18` (i.e. the old Flang driver) 2021-08-05 12:57:15 +00:00