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

            Bug ID: 85160
           Summary: GCC generates mvn/and instructions instead of bic on
                    aarch64
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sje at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64

With this test case:

int foo(int a, int b, int *c, int i, int j)
{
        int x,y;
        x = ((a & (~c[i])) >> 7) |
             ((a & (~c[j])) >> 9);
        y = ((b & (~c[i])) >> 9) |
             ((b & (~c[j])) >> 7);
        return x | y;
}

GCC -O2 generates 2 'mvn' instructions and 4 'and' instructions.
LLVM -O2 generates 4 'bic' instructions instead.

GCC:

foo:
        ldr     w3, [x2, w3, sxtw 2]
        ldr     w2, [x2, w4, sxtw 2]
        mvn     w3, w3
        mvn     w2, w2
        and     w4, w3, w1
        and     w1, w2, w1
        and     w3, w3, w0
        and     w2, w2, w0
        asr     w4, w4, 9
        asr     w1, w1, 7
        orr     w3, w4, w3, asr 7
        orr     w2, w1, w2, asr 9
        orr     w0, w3, w2
        ret

LLVM:

foo:
        ldr     w8, [x2, w3, sxtw #2]
        ldr     w9, [x2, w4, sxtw #2]
        bic     w10, w0, w8
        bic     w8, w1, w8
        asr     w8, w8, #9
        bic     w11, w0, w9
        orr     w8, w8, w10, asr #7
        bic     w9, w1, w9
        orr     w8, w8, w11, asr #9
        orr     w0, w8, w9, asr #7
        ret


I am not sure if this should be considered target specific or not, the 'bic'
instruction is aarch64 specific but GCC knows how to use it.  I think combine
didn't try to replace the mvn instructions because it is used by two subsequent
instructions and that may be a generic combine issue.

Reply via email to