how to disable cmov generation?

Hi,

sometimes llvm/clang generates conditional mov in the code wenn
optimization is enabled.

Is there a way that I can tell the compiler not to generate cmov
instructions?

gcc has the -fno-if-conversion and -fno-if-conversion2 for that, but so
far I have found not an equivalent in clang.

Thanks!

Regards,
Marc

Why do you want to do that? We intentionally don't have a flag for every
single transformation.

Joerg

sometimes llvm/clang generates conditional mov in the code wenn
optimization is enabled.

Is there a way that I can tell the compiler not to generate cmov
instructions?

Why do you want to do that? We intentionally don't have a flag for
every single transformation.

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.

For our gcc plugin we can avoid this by said -f... parameters.
For llvm we we are still looking for a solution thats why I write here.
Worst solution would be checking for iselect and adding phi nodes
accordingly. But that would be quite some work as that would need to be
done for several modules.

And such an -f option would also be beneficial for a whole range of
other fuzzers. Even libfuzzer (-fsanitize-coverage):
   0x0000000000423cfd <+269>: cmp cl,0x41
   0x0000000000423d00 <+272>: cmove ebp,r13d

Regards,
Marc

Hi,

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.

David

I am not sure I know what you mean.
Yes I could implement something in your coverage plugins (they run at
EP_OptimizerLast), but that misses the point and is something I would do
as a last resort.

The issue affects all fuzzers, also libfuzzer, honggfuzz etc.
Also if you just use -fsanitize-coverage=trace-pc-guard.
So that not everyone has to implement something for this it would be
beneficial if there would be an option in clang for that - like gcc has
- if it does not have this feature already (and it is currently
undocumented).

So thats why I am asking if there is this feature already and if not if
there is someone who says "right, that is an issue, that feature would
be beneficial to have".

Regards,
Marc