Гарантируется ли замена функций gcc __builtin соответствующими инструкциями по сборке? - PullRequest
0 голосов
/ 07 ноября 2018

На ARM Cortex-M3, например, присутствует команда CLZ , она считает начальные нули 32-битного целого числа. Если целое число равно нулю, результат равен 32.

С другой стороны, в gcc я могу использовать функцию __builtin_clz. Однако согласно документации gcc:

Встроенная функция: int __builtin_clz (без знака int x).
Возвращает количество ведущих 0-битов в x, начиная с самой старшей позиции бита. Если x равен 0, результат не определен .

Так что, если использовать эту встроенную функцию, я должен вручную обработать ноль? Или это гарантированно будет скомпилировано в инструкцию CLZ, если такая инструкция присутствует на целевой машине?

Цитаты из документации по gcc высоко ценятся!

1 Ответ

0 голосов
/ 07 ноября 2018

Встроенные функции обеспечивают функции, описанные для них. Они не гарантируют компиляцию по конкретным инструкциям.

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

Компилятор может свободно реализовывать встроенные функции любым способом, который предоставляет указанные функции. Поскольку указанная функция имеет неопределенное поведение для нуля, вы не можете ожидать, что компилятор предоставит желаемое поведение для нуля, с помощью инструкции clz или иным образом.

Мы можем ожидать, что оптимизация будет обычно использовать очевидные инструкции, когда это необходимо. Но компилятор может также комбинировать встроенные функции с другим кодом (возможно, приводящим к последовательности кода, в которой обычная инструкция не требуется или другая инструкция лучше), оценивать константные выражения во время компиляции и делать другие неочевидные оптимизации. Учтите, что если компилятор распознает путь к коду, в котором аргумент __builtin_clz равен нулю, он может заменить этот путь на что угодно, включая полное его удаление, поскольку его поведение не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...