This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFC: Combine of compare & and oddity
- From: "Wilco Dijkstra" <wdijkstr at arm dot com>
- To: "'GCC Patches'" <gcc-patches at gcc dot gnu dot org>, "'Segher Boessenkool'" <segher at kernel dot crashing dot org>
- Date: Wed, 2 Sep 2015 18:09:24 +0100
- Subject: RFC: Combine of compare & and oddity
- Authentication-results: sourceware.org; auth=none
Hi,
Combine canonicalizes certain AND masks in a comparison with zero into extracts of the widest
register type. During matching these are expanded into a very inefficient sequence that fails to
match. For example (x & 2) == 0 is matched in combine like this:
Failed to match this instruction:
(set (reg:CC 66 cc)
(compare:CC (zero_extract:DI (subreg:DI (reg/v:SI 76 [ xD.2641 ]) 0)
(const_int 1 [0x1])
(const_int 1 [0x1]))
(const_int 0 [0])))
Failed to match this instruction:
(set (reg:CC 66 cc)
(compare:CC (and:DI (lshiftrt:DI (subreg:DI (reg/v:SI 76 [ xD.2641 ]) 0)
(const_int 1 [0x1]))
(const_int 1 [0x1]))
(const_int 0 [0])))
Neither matches the AArch64 patterns for ANDS/TST (which is just compare and AND). If the immediate
is not a power of 2 or a power of 2 -1 then it matches correctly as expected.
I don't understand how ((x >> 1) & 1) != 0 could be a useful expansion (it even uses shifts by 0 at
times which are unlikely to ever match anything). Why does combine not try to match the obvious (x &
C) != 0 case? Single-bit and mask tests are very common, so this blocks efficient code generation on
many targets.
It's trivial to change change_zero_ext to expand extracts always into AND and remove the redundant
subreg. However wouldn't it make more sense to never special case certain AND immediate in the first
place?
Wilco