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.