middle-end: Restore MEM_NOTRAP for memory-only loads [PR127185]

EXPAND_MEMORY requires a MEM result but does not state whether the access
is a load or a store.  Its conservative store semantics avoid unsafe
MEM_NOTRAP claims, but two known load callers lose valid nontrapping
information.

On this patch's parent, a memory-only inline asm input is:

  (mem/u:SI (...) [ input+0 ])

Restore its load semantics:

  (mem/u/c:SI (...) [ input+0 ])

The partial-load expander has the same problem.  It uses EXPAND_WRITE even
though its MEM is the source of a masked or length-limited load.  Its source
MEM changes from:

  (mem/u:V4SI (...))

to:

  (mem/u/c:V4SI (...))

Use EXPAND_MEMORY for partial loads because they require a MEM, then set
MEM_NOTRAP from tree_could_trap_p at both caller sites.

Bootstrapped and tested on aarch64-unknown-linux-gnu.  Tested on
x86_64-pc-linux-gnu.

	PR middle-end/127185

gcc/ChangeLog:

	* cfgexpand.cc (expand_asm_stmt): Restore load MEM_NOTRAP for memory
	inputs.
	* internal-fn.cc: Include tree-eh.h.
	(expand_partial_load_optab_fn): Expand the source as memory and
	restore load MEM_NOTRAP.

gcc/testsuite/ChangeLog:

	* g++.dg/opt/mem-notrap-load-asm.C: New test.
	* gcc.target/i386/mem-notrap-mask-load.c: New test.

Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
4 files changed