llvm-project
f431b456 - [flang] Fix incorrect DSE of VALUE dummy arg copy stores due to TBAA mismatch (#215366)

Commit
50 days ago
[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
Author
Parents
Loading