-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Closed
Description
This is an optimization opportunity that can benefit RISC-V, MIPS and other processors that don't use condition codes for their compare-and-branch instructions.
#include <stdlib.h>
unsigned int func1_a(unsigned int x) {
if (x != 0x555)
return (x ^ 0x555);
abort();
}
unsigned int func1_c(unsigned int x) {
unsigned int tmp = x ^ 0x555;
__asm__ ("" : "+r" (tmp));
if (tmp == 0)
abort();
return tmp;
}
unsigned int func2_a(unsigned int x) {
if (x != 0x555)
return (x - 0x555);
abort();
}
unsigned int func2_c(unsigned int x) {
unsigned int tmp = x - 0x555;
__asm__ ("" : "+r" (tmp));
if (tmp == 0)
abort();
return tmp;
}The example code above can be tested in Compiler Explorer (godbolt.org). (The target architecture I mostly concern here is riscv32.)
func1_c() and func2_c() are the results I expected for func1_a() and func2_a() to optimize to when using the -Os option. Clang 19 is already able to recognize the func2 case (x != 0x555 and x - 0x555 != 0) but misses on the func1 case ((x ^ 0x555) != 0).
(Note: I also reported this in GCC.)