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