match-sat-alu.pd: Recognize X - MIN (X, Y) as saturating subtraction

X - MIN (X, Y) is unsigned saturating subtraction, but subtraction
statements were not checked for this form.

Recognize the form and check MINUS_EXPR statements for saturation.  Require
the MIN to have one use so that the replacement removes it.  Make the assign
recognizers report whether they replaced the statement, and do not run later
transforms after a replacement.

AArch64 -O2:

before:

	cmp	w1, w0
	csel	w1, w1, w0, ls
	sub	w0, w0, w1

after:

	subs	w0, w0, w1
	csel	w0, w0, wzr, cs

The vector form becomes one UQSUB instead of a comparison, a select, and a
subtraction.

Bootstrapped and tested on aarch64-none-linux-gnu.

gcc/ChangeLog:

	* match-sat-alu.pd (unsigned_integer_sat_sub): Add the
	X - MIN (X, Y) form.
	* tree-ssa-math-opts.cc
	(build_saturation_binary_arith_call_and_replace): Return whether a
	replacement was made.
	(match_saturation_add_with_assign): Likewise.
	(match_unsigned_saturation_sub): Likewise.
	(math_opts_dom_walker::after_dom_children): Check MINUS_EXPR for
	saturation, and use the assign recognizer results.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sat_u_sub_minmax-1.c: New test.
	* gcc.target/aarch64/sat_u_sub_minmax-2.c: New test.
	* gcc.target/aarch64/sat_u_sub_minmax-3.c: New test.

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