middle-end: Check GIMPLE memory LHSs as stores [PR127184]

tree_could_trap_p describes evaluation as an rvalue.  However,
gimple_could_trap_p_1 uses it for an assignment LHS when store checks are
requested.  It also scans the LHS of other statements as an rvalue.  A load
can be safe while a store to the same address can trap.

Use gimple_store_p and lhs_could_trap_p for memory LHSs when store checks are
requested.  This keeps register definitions as non-stores and includes memory
results of GIMPLE_CALL.  Omit every statement LHS from the rvalue operand
scan.

A nothrow call statement can still trap when the caller stores its result.
The return-slot optimization flag permits direct construction in the
destination, but expansion can use a temporary and a caller-side copy.  Check
a memory call LHS when non-call exceptions are enabled.

Add self-tests for register definitions, assignment stores, and call result
stores.  Add a non-call exception test for nothrow call results.

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

	PR middle-end/127184

gcc/ChangeLog:

	* gimple.cc (gimple_could_trap_p_1): Check a memory LHS with
	lhs_could_trap_p.  Do not inspect an LHS as an rvalue.
	(test_could_trap): New self-test.
	(gimple_cc_tests): Run it.
	* tree-eh.cc (stmt_could_throw_p): Check a nothrow call's memory LHS.

gcc/testsuite/ChangeLog:

	* g++.dg/eh/noncall-store-call.C: New test.

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