https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78317
--- Comment #5 from dhowells at redhat dot com <dhowells at redhat dot com> --- Note that the issue doesn't require the value to be returned directly to trigger it: struct A { unsigned a; }; struct B { unsigned b; }; unsigned test5(struct A *x, struct B *y) { unsigned z = 0; if (x->a & 0x10) z |= 0x10; if (x->a & 0x40) z |= 0x40; y->b = z; } is rendered as: 52: 8b 17 mov (%rdi),%edx 54: b9 10 00 00 00 mov $0x10,%ecx 59: 89 d0 mov %edx,%eax 5b: 83 e0 10 and $0x10,%eax 5e: 0f 45 c1 cmovne %ecx,%eax 61: 89 c1 mov %eax,%ecx 63: 83 c9 40 or $0x40,%ecx 66: 80 e2 40 and $0x40,%dl 69: 0f 45 c1 cmovne %ecx,%eax 6c: 89 06 mov %eax,(%rsi) 6e: c3 retq by gcc -Os, but: 23: 8b 07 mov (%rdi),%eax 25: 83 e0 50 and $0x50,%eax 28: 89 06 mov %eax,(%rsi) 2a: c3 retq by clang -Os.