Встроенные функции обеспечивают функции, описанные для них. Они не гарантируют компиляцию по конкретным инструкциям.
Обратите внимание, что в документации GCC говорится, что это функции: «GCC предоставляет большое количество встроенных функций». Он не говорит вам, что они генерируют конкретные инструкции. Для __builtin_clz
он говорит: «Возвращает количество старших 0-битов в x, начиная с самой старшей позиции бита. Если х равен 0, результат не определен ». Документация здесь просто означает, что в нем говорится: __builtin_clz
- это функция, которая возвращает число старших 0-битов в х, начиная с самой старшей позиции бита, и, если х 0, результат не определен. В документации нет заявления о том, что __builtin_clz
предоставляет инструкцию считать-ведущими-нулями, поэтому вы не можете ожидать, что она предоставит инструкцию-подсчету-ведущим нулей.
Компилятор может свободно реализовывать встроенные функции любым способом, который предоставляет указанные функции. Поскольку указанная функция имеет неопределенное поведение для нуля, вы не можете ожидать, что компилятор предоставит желаемое поведение для нуля, с помощью инструкции clz
или иным образом.
Мы можем ожидать, что оптимизация будет обычно использовать очевидные инструкции, когда это необходимо. Но компилятор может также комбинировать встроенные функции с другим кодом (возможно, приводящим к последовательности кода, в которой обычная инструкция не требуется или другая инструкция лучше), оценивать константные выражения во время компиляции и делать другие неочевидные оптимизации. Учтите, что если компилятор распознает путь к коду, в котором аргумент __builtin_clz
равен нулю, он может заменить этот путь на что угодно, включая полное его удаление, поскольку его поведение не определено.