https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93940
Bug ID: 93940
Summary: crazy codegen bug on Og with builtin_constant_p,
coverage, and pthread
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: barry.revzin at gmail dot com
Target Milestone: ---
This holds for gcc 8.x, 9.x, and trunk. The following program (thanks,
creduce):
using uint16_t = unsigned short;
struct a {
uint16_t b = 0;
};
struct c {
short d;
};
class e {
public:
void f();
void init_session(c);
};
#ifdef ADD_CONSTEXPR
#define CONSTEXPR constexpr
#else
#define CONSTEXPR
#endif
auto htons = [](uint16_t s) {
if CONSTEXPR (__builtin_constant_p(s)) {
return uint16_t(uint16_t(s >> 8) | uint16_t(s << 8));
} else {
return uint16_t(uint16_t(s >> 8) | uint16_t(s << 8));
}
};
struct g {
e h;
void i(a k) {
h.f();
auto j = c();
j.d = htons(k.b);
h.init_session(j);
}
};
void test() {
g().i({});
}
The htons lambda is mimicking the htons macro, which leads with the
__builtin_constant_p check before doing either a different builtin or direct
asm. In this case, the __builtin_constant_p appears to be significant but the
rest not so much.
When compiling the above with -std=c++17 -Og -pthread --coverage, the generated
asm for test() is:
test():
sub rsp, 24
lock add QWORD PTR __gcov0.test()[rip], 1
lock add QWORD PTR __gcov0._ZN1g1iE1a[rip], 1
lea rdi, [rsp+15]
call e::f()
That's it. It only calls f(), there is no call to init_session().
On the other hand, when compiling the above with -std=c++17 -Og -pthread
--coverage -DADD_CONSTEXPR, the generated asm for test() is:
test():
sub rsp, 24
lock add QWORD PTR __gcov0.test()[rip], 1
lock add QWORD PTR __gcov0._ZN1g1iE1a[rip], 1
lea rdi, [rsp+15]
call e::f()
lock add QWORD PTR __gcov0._ZN1g1iE1a[rip+8], 1
mov esi, 0
lea rdi, [rsp+15]
call e::init_session(c)
lock add QWORD PTR __gcov0._ZN1g1iE1a[rip+16], 1
lock add QWORD PTR __gcov0.test()[rip+8], 1
add rsp, 24
ret
It seems that this whole combination of flags (-Og, pthread, coverage) is
significant, as is the fact that htons is a lambda and not a function, as are
all sorts of other things. I have no idea.
Link to compiler explorer: https://godbolt.org/z/6pgLF_