https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116013
Bug ID: 116013 Summary: Missed optimization opportunity with andn involving consts Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: bisqwit at iki dot fi Target Milestone: --- Below are two short functions which work identically. While GCC utilizes the ANDN instruction (of Intel BMI1) for test2, it fails to see that it could do the same with test1. #include <stdint.h> uint64_t test1(uint64_t value) { return ~(value | 0x7F7F7F7F7F7F7F7F); } uint64_t test2(uint64_t value) { return ~value & ~0x7F7F7F7F7F7F7F7F; } Assembler listings of both functions are below (-Ofast -mbmi): test1: movabsq $9187201950435737471, %rdx movq %rdi, %rax orq %rdx, %rax notq %rax ret test2: movabsq $-9187201950435737472, %rax andn %rax, %rdi, %rax ret Tested compiler version: GCC: (Debian 14-20240330-1) 14.0.1 20240330 (experimental) [master r14-9728-g6fc84f680d0] This optimization makes only sense if one of the operands is a compile-time constant. If neither operand is a compile-time constant, then the opposite optimization makes more sense — which GCC already does. It is also worth noting, that GCC already compiles ~(var1 | ~var2) into ~var1 & var2, utilizing ANDN. This is good.