https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611
--- Comment #6 from Ryan Johnson <scovich at gmail dot com> --- (In reply to Jeremy from comment #5) > It may not be possible, but perhaps a simpler thing might be for > the asm() to notionally "return" a single boolean value which > reflects ONE flag only. Interesting! Ironically, limiting it to one flag opens the way to cleanly specify branching based on multiple flags. The optimizer just needs to recognize that when it sees two otherwise-equivalent (non-volatile) asm statements with different asm_return attribute, it's really just one asm statement that sets multiple flags. Thus: #ifdef USE_ASM #define CMP(a,b) asm("cmp %0 %1" : : "r"(a), "r"(b)) #define BELOW(a,b) (__attribute__((asm_return(cc_carry))) CMP(a,b)) #define EQUAL(a,b) (__attribute__((asm_return(cc_zero))) CMP(a,b)) #else #define BELOW(a,b) ((a) < (b)) #define EQUAL(a,b) ((a) == (b)) #endif int do_it(unsigned int a, unsigned int b, int c, int d, int e, int f) { int x; if (BELOW(a,b)) x = c+d; else if (EQUAL(a,b)) x = d+e; else x = c+e; return x+f; } Would produce the same assembly code output---with only one comparison---whether USE_ASM was defined or not. Even more fun would be if the optimizer could recognize conditionals that depend on multiple flags (like x86 "less or equal") and turn this: if ((__attribute__((asm_return(cc_zero))) CMP(a,b) || __attribute__((asm_return(cc_overflow))) CMP(a,b) != __attribute__((asm_return(cc_sign))) CMP(a,b)) do_less_or_equal(); do_something_else(); into: cmp %[a] %[b] jg 1f call do_less_or_equal 1: call do_something_else Much of the flag-wrangling machinery seems to already exist, because the compiler emits the above asm if you replace the inline asm with either "a <= b" or "a < b || a == b" (assuming now that a and b are signed ints).