James, The subtract instruction only reliably sets the N and Z flags. We convey this information in aarch64_seelct_cc_mode.
Regards, Michael Collison -----Original Message----- From: James Greenhalgh [mailto:james.greenha...@arm.com] Sent: Monday, July 10, 2017 10:12 AM To: Michael Collison <michael.colli...@arm.com> Cc: gcc-patches@gcc.gnu.org; nd <n...@arm.com> Subject: Re: [PATCH][Aarch64] Relational compare zero not merged into subtract On Thu, Jun 01, 2017 at 11:54:33PM +0000, Michael Collison wrote: > This patch improves code generation for relational compares against > zero that are not merged into a subtract instruction. This patch > improves the >= and < cases. > > An example of the '<' case: > > int lt (int x, int y) > { > if ((x - y) < 0) > return 10; > > return 0; > } > > Trunk generates: > > lt: > sub w1, w0, w1 > mov w0, 10 > cmp w1, 0 > csel w0, w0, wzr, lt > ret > > With the patch we can eliminate the redundant subtract and now generate: > > lt: > cmp w0, w1 > mov w0, 10 > csel w0, w0, wzr, mi > ret I'm not up to speed on the way we use CC register modes in the AArch64 Backend. On the one hand looking at patterns like *sub<mode>3_compare0, this patch looks correct. Those too generate subs instructions, and only set the CC_NZ CC register. But on the other hand cmp<mode> sets the full CC register. As cmp is an alias for subs, should they not set the same CC register mode? Certainly the instruction sets more than just N and Z. As I say, I don't understand this area, and I'm not sure if my objection is reasonable. Hopefully someone who knows CC modes better could help me understand why this is correct. Thanks, James > > Bootstrapped and tested on aarch64-linux-gnu. Okay for trunk? > > 2017-06-01 Michael Collison <michael.colli...@arm.com> > > * config/aarch64/aarch64-simd.md(aarch64_sub<mode>_compare0): > New pattern. > * testsuite/gcc.target/aarch64/cmp-2.c: New testcase.