[flang] Fix incorrect DSE of VALUE dummy arg copy stores due to TBAA mismatch (#215366)
Assisted by : IBM Bob
**Problem:**
When a BIND(C) derived-type dummy argument with the VALUE attribute is
large
enough to be passed on the stack (e.g. PPC64 byval ABI), Flang lowers it
as
a local `fir.alloca` with a `fir.declare` carrying
`fortran_attrs = value`. Before this fix, `AddAliasTags` classified
accesses
to that alloca under the `"allocated data"` TBAA subtree
(`SourceKind::Allocate`). However, other accesses to the same dummy
variable
were tagged under the `"dummy arg data"` subtree
(`SourceKind::Argument`).
Because these two subtrees are siblings under `"any data access"`,
LLVM's
`DSEPass` treated the copy-stores as non-aliasing with the subsequent
reads
and incorrectly eliminated them. At `-O3`, reads of the VALUE copy
returned
garbage, causing wrong results or `ERROR STOP`.
**Fix:**
in `AddAliasTags.cpp`, detect when a `SourceKind::Allocate` source is a
VALUE dummy arg copy by checking for
`fir::FortranVariableFlagsEnum::value`
on its `fir.declare`. Tag such accesses under `dummyArgDataTree` instead
of
`allocatedDataTree`, making them consistent with the dummy arg reads and
preventing DSE from eliminating the stores.
**Reproducer** (fails at `-O3`, passes at `-O0`, before fix):
```fortran
module m
use ISO_C_BINDING
type, bind(c) :: dtd0; integer(C_INT_LEAST8_T) :: a(10,5); end type
type, bind(c) :: dtd1
integer(C_INT_LEAST8_T) :: a(10,5); type(dtd0) :: d0
end type
end module m
program p
use m
interface
integer(C_INT_LEAST8_T) function fnt4(dt) bind(c)
import; type(dtd1), value :: dt
end function
end interface
type(dtd1) :: dtb; integer ret
dtb%a = 1_1; dtb%d0%a = 1_1
ret = fnt4(dtb)
end program p
integer(C_INT_LEAST8_T) function fnt4(dt) bind(c)
use ISO_C_BINDING, only: C_INT_LEAST8_T
use m, only: dtd0, dtd1
type(dtd1), value :: dt
do i = 1, 5; do j = 1, 10
if (dt%a(j,i) /= 1) ERROR STOP 156
dt%a(j,i) = 2
if (dt%d0%a(j,i) /= 1) ERROR STOP 158
dt%d0%a(j,i) = 2
end do; end do
fnt4 = 0
end function fnt4