https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87104

pipcet at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  Attachment #44605|0                           |1
        is obsolete|                            |
  Attachment #44606|0                           |1
        is obsolete|                            |

--- Comment #11 from pipcet at gmail dot com ---
Created attachment 44617
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44617&action=edit
WIP patch

I'm having partial success with this patch, which does two things:

1. Canonicalize to the easier-to-read (X & A) == B form
2. Emit optimized lea-test sequence for (X & A) == B

(1) is straightforward; we need a new routine to test that an integer
masks a contiguous range of bit positions.

(2) is straightforward except for there being three cases: 32-bit,
64-bit, and mixed. Emacs uses the mixed case, where the lower 3 bits
of a 64 bit value are tested.

The strange thing is that code like

int h17(long int i)
{
  if ((i & 12) == 12)
    return 1;
  return 0;
}

does not work.  I see this intermediate RTL:

 (insn 7 6 8 2 (set (reg:CCZ 17 flags)
         (compare:CCZ (and:DI (not:DI (reg/v:DI 86 [ i ]))
                 (const_int 12 [0xc]))
             (const_int 0 [0]))) "h17.c":4 15 {*cmpdi_1}
      (expr_list:REG_DEAD (reg:DI 88)

Surely we should be dealing with a canonical form instead?  Who's
generating this non-canonical expression, and why?

Is it legal to do something like
  {
    operands[2] = negate_rtx (operands[2]);
  }
in a define_split? That would avoid the need to generate complicated
RTL exprs from C.

Anyway, this all needs more work and much more testing, but it's a start.

Reply via email to