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

--- Comment #6 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Consider two arms where the constants differ by a single bit.  That's a
conditional IOR/PLUS of a shifted condition code.  And if the shift count is
small enough it turns into a shadd ;-)  Consider:


int src(int c, int b, int a) {
  int t = (a ? 0xff00 : 0xff08);
  return t;
}

RIght now that generates something like this:

        li      a5,65536
        li      a4,65536
        addi    t0,a5,-248
        addi    t1,a4,-256
        czero.nez       t2,t0,a2
        czero.eqz       a2,t1,a2
        add     a0,t2,a2

Which is better than a branch, but otherwise awful.  This would be clearly
better and isn't a major stretch for the shifted_store_flag routine

        li      a5,65536
        seqz    a0,a2
        addi    t0,a5,-256
        sh3add  a0,a0,t0

It's a cycle faster and 10 bytes shorter.


If I go back to Andrea's original testcase I get this with my hacks:

src:
        seqz    a2,a2
        li      a0,65536
        slli    t0,a2,4
        addi    t1,a0,-256
        add     a0,t1,t0
        ret


Which is clearly better than what we're doing now.

So what I'm thinking is we carve this into two or more BZs.  One for the case
where we're dealing with a single bit adjustment as that's going to be fairly
easy to implement in the shifted_store_flag routine (original case).  A second
for cases where we differ by multiple bits, but it's still a simm12 we're
dealing with (case in c#1)

Reply via email to