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

Reply via email to