>> 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 -- Marc Heuse www.mh-sec.de PGP: AF3D 1D4C D810 F0BB 977D 3807 C7EE D0A0 6BE9 F573
David Chisnall via llvm-dev
2021-Oct-29 13:12 UTC
[llvm-dev] how to disable cmov generation?
Hi, 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. David