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

            Bug ID: 91504
           Summary: Inlining misses some logical operation folding
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rth at gcc dot gnu.org
  Target Milestone: ---

In the following test case,

static inline unsigned deposit32(unsigned value, int start, int length,
                                 unsigned fieldval)
{
    unsigned mask = (~0U >> (32 - length)) << start;
    return (value & ~mask) | ((fieldval << start) & mask);
}

unsigned foo(unsigned value)
{
   return deposit32(value, 10, 1, 1);
}

unsigned bar(unsigned value)
{
    int start = 10;
    int length = 1;
    unsigned fieldval = 1;
    unsigned mask = (~0U >> (32 - length)) << start;
    return (value & ~mask) | ((fieldval << start) & mask);
}

One would expect FOO and BAR to compile to the same code, since
the latter is the trivial inlining of the former, but that does
not happen.

gcc -O2 -S z.c gives

foo:
        mvn     w1, w0
        and     w1, w1, 1024
        eor     w0, w1, w0
        ret

bar:
        orr     w0, w0, 1024
        ret

The problem appears independent of target, as it isvisible on
both x86 and aarch64 targets.

Reply via email to