gnu/gcc/a0cbca7aefb94b0241e706fe737e0326eead413d strub: Preserve load MEM_NOTRAP for watermarks [PR127185]
expand_builtin_strub_update expands a watermark with EXPAND_MEMORY because
it needs a MEM. The same MEM is first loaded for a comparison and can then
be the destination of a store. EXPAND_MEMORY has conservative store
semantics, so the load loses its valid MEM_NOTRAP flag:
(set (reg:DI ...)
(mem/f:DI (... watermark_ptr ...)))
(set (mem/f:DI (... watermark_ptr ...))
(reg:DI ...))
Make a shallow copy for the load and derive its MEM_NOTRAP flag with load
trap semantics. Keep the original MEM for the store:
(set (reg:DI ...)
(mem/f/c:DI (... watermark_ptr ...)))
(set (mem/f:DI (... watermark_ptr ...))
(reg:DI ...))
This keeps the memory-result requirement and does not mark the conditional
store as nontrapping. Apply load trap semantics to the load-only watermarks
in expand_builtin_strub_leave as well.
Tighten the existing update test so that it identifies the load and store
positions independently of the target mode and MEM flag order. Add a nested
at-calls test that checks the incoming watermark loads from both update and
leave.
Bootstrapped and tested on aarch64-unknown-linux-gnu. Tested on
x86_64-pc-linux-gnu.
PR middle-end/127185
gcc/ChangeLog:
* builtins.cc (expand_builtin_strub_update): Use a separate MEM with
load trap semantics for each watermark load.
(expand_builtin_strub_leave): Use load trap semantics for watermark
MEMs.
gcc/testsuite/ChangeLog:
* c-c++-common/strub-mem-notrap.c: Tighten the load and store scans.
* c-c++-common/strub-mem-notrap-leave.c: New test.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
3 files changed