This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][AArch64] Fix missing optimization for CMP+AND
- From: James Greenhalgh <james dot greenhalgh at arm dot com>
- To: Sudi Das <Sudi dot Das at arm dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, nd <nd at arm dot com>, Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Date: Thu, 27 Jul 2017 17:31:09 +0100
- Subject: Re: [PATCH][AArch64] Fix missing optimization for CMP+AND
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=pass (sender IP is 217.140.96.140) smtp.mailfrom=arm.com; gcc.gnu.org; dkim=none (message not signed) header.d=none;gcc.gnu.org; dmarc=bestguesspass action=none header.from=arm.com;
- Nodisclaimer: True
- References: <AM3PR08MB0625D1926EE420C4A2DAAE9498350@AM3PR08MB0625.eurprd08.prod.outlook.com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
On Wed, Mar 29, 2017 at 11:17:20AM +0100, Sudi Das wrote:
>
> Hi all
>
> During combine GCC tries to merge CMP (with zero) and AND into a TST.
> However, in cases where an ANDS operand is not compatible, this was being
> missed. Adding a define_split where this operand was moved to a register
> seems to help out.
>
> For example for a test :
>
> int
> f (unsigned char *p)
> {
> return p[0] == 50 || p[0] == 52;
> }
>
> int
> g (unsigned char *p)
> {
> return (p[0] >> 4 & 0xfd) == 0;
> }
>
> we are now generating
>
> f:
> ldrb w0, [x0]
> mov w1, 253
> sub w0, w0, #50
> tst w0, w1
> cset w0, eq
> ret
> .size f, .-f
> .align 2
> .p2align 3,,7
> .global g
> .type g, %function
> g:
> ldrb w1, [x0]
> mov w0, 13
> tst w0, w1, lsr 4
> cset w0, eq
> ret
>
> instead of
>
> f:
> ldrb w0, [x0]
> sub w0, w0, #50
> and w0, w0, -3
> and w0, w0, 255
> cmp w0, 0
> cset w0, eq
> ret
> .size f, .-f
> .align 2
> .p2align 3,,7
> .global g
> .type g, %function
> g:
> ldrb w0, [x0]
> lsr w0, w0, 4
> and w0, w0, -3
> cmp w0, 0
> cset w0, eq
> ret
>
> Added this new test and checked for regressions on bootstrapped
> aarch64-none-linux-gnu Ok for stage 1?
Sorry to have let this slip for so long.
I've committed this on your behalf as revision 250631.
Thanks,
James
>
> Thanks
> Sudi
>
> 2017-03-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
> Sudakshina Das <sudi.das@arm.com>
>
> * config/aarch64/aarch64.md (define_split for and<mode>3nr_compare0): Move
> non aarch64_logical_operand to a register.
> (define_split for and_<SHIFT:optab><mode>3nr_compare0): Move non register
> immediate operand to a register.
>
> * config/aarch64/predicates.md (aarch64_mov_imm_operand): New.
>
> 2017-03-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
> Sudakshina Das <sudi.das@arm.com>
>
> * gcc.target/aarch64/tst_imm_split_1.c: New Test.