On 09/02/2015 11:09 AM, Wilco Dijkstra wrote:
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])))
That's a fairly standard looking bit test One could argue about the
mode of the extraction being problematical because it introduces the
SUBREG, but overall it's a normal looking bit test. Various ports know
about this form.
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])))
Yea, this is an alternative form. I don't offhand remember how/why
this form appears, but it certainly does. I don't think any ports
handle this form (but I certainly have done any checks), but I believe
combine creates it primarily for internal purposes.
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.
It might be advisable to recognize the first form.
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.
From md.texi:
cindex @code{zero_extract}, canonicalization of
@cindex @code{sign_extract}, canonicalization of
@item
Equality comparisons of a group of bits (usually a single bit) with zero
will be written using @code{zero_extract} rather than the equivalent
@code{and} or @code{sign_extract} operations.
Jeff