[llvm-dev] how to disable cmov generation?

David Chisnall via llvm-dev llvm-dev at lists.llvm.org
Fri Oct 29 06:12:23 PDT 2021


On 29/10/2021 08:15, Marc via llvm-dev wrote:
> I am the maintainer of the afl++ fuzzer, and we write our own llvm
> plugins for instrumenting the binaries.
> The problem with cmov is that it hides if () ...; else ... ;and
> therefore we do not see edges.

To clarify, are you doing this as an IR transform or a binary rewrite? 
The question has very different answers depending on this.

There are different places where a branch may be converted to a cmov 
instruction and there is no guarantee for any given back end that either 
an IR select or a small basic block with a single PHI node would be 
lowered as a branch or as a cmov.  There is also no guarantee that front 
ends won't insert select instructions directly.

It would be possible to modify back ends to never lower short branches 
to conditional moves (though this would require a specific code-gen 
option and would need to be done for every back end) and add a pass that 
expands selects to branches (I think we used to have one for debugging, 
not sure if it's still around).

I presume that the reason that you want this information is to get 
coverage information.  If you're doing an IR transformation then you'd 
probably be better served by identifying select instructions and mapping 
the condition to your coverage table in the same way that you map branch 
conditions.  This would avoid introducing branching control flow and 
would still give you the output that you want.

Alternatively, if your pass runs before any if conversion then, for 
front ends that don't insert select instructions directly, your 
instrumentation would be preserved by any later transforms and so 
whether a given branch in the IR is lowered to a jump or to a 
conditional move is irrelevant: your instrumentation code will still 
track which logical branch was taken.

I'd recommend the first approach though because there is absolutely no 
requirement that front ends ever emit branches rather than select 
instructions.  There isn't really anything in C that maps trivially to 
select (even ternary operators are short-circuiting so you need to know 
that neither path has side effects and both are short enough that a 
branch costs more than executing both paths to be able to do the 
transform) but that isn't universally true and some front ends will emit 
selects directly.


More information about the llvm-dev mailing list