There is code in the expanders which is supposed to avoid emitting calls to pure functions which have their result ignored, but it doesn't appear to work when the function called is represented as a COND_EXPR.
Created attachment 11850 [details] test case The available source code for the functions allows the compiler to see that the called functions are const. This should be sufficient for the compiler to figure out the call is not needed. Likewise, the pure attributes should also be sufficient to figure this out.
Confirmed.
This works for 'const' functions because they stick on the function type as well. The attributes are only on the DECL and do not get merged and transfered to the resulting function type of the COND_EXPR. So this again asks for streamlining attributes on types vs. decls.
GCC trunk today on x86-64 produces: gen_x86_64_shrd(int): xorl %eax, %eax ret ok(int): movl $1, %eax ret ix86_split_ashr(int): testl %edi, %edi movl $ok(int), %eax movl $gen_x86_64_shrd(int), %edx cmove %rdx, %rax xorl %edi, %edi jmp *%rax FWIW clang trunk also does not optimize this, yielding: ix86_split_ashr(int): # @ix86_split_ashr(int) testl %edi, %edi movl $gen_x86_64_shrd(int), %eax movl $ok(int), %ecx cmoveq %rax, %rcx xorl %edi, %edi jmpq *%rcx # TAILCALL ok(int): # @ok(int) movl $1, %eax retq gen_x86_64_shrd(int): # @gen_x86_64_shrd(int) xorl %eax, %eax retq ICC 19.0.1 _does_ optimize, resulting in: ix86_split_ashr(int): ret #24.1 _INTERNALf242c0c5::gen_x86_64_shrd(int): xorl %eax, %eax #6.10 ret #6.10 _INTERNALf242c0c5::ok(int): movl $1, %eax #12.10 ret #12.10