Нет, это пропущенная оптимизация GCC ;что C может юридически быть в первую очередь для продления знака.Вы должны сообщить об этом в bugzilla GCC с ключевым словом «пропущенная оптимизация».
clang, ICC и MSVC ( на Godbolt ) скомпилировать его в ожидаемый
f:
movsbl c(%rip), %eax # sign extend first
xorl $1, %eax
retq
Даже попытка удержать GCC в этом коде с этим C не может заставить GCC сделать это:
int f() {
int tmp = c;
tmp ^= 1;
return tmp;
}
Я предполагаю, что, возможно, GCC решит просто загрузить 1 байти продлите знак после вместо ранее.ИДК, почему он считает, что это хорошая идея.Но в любом случае, чтобы избежать ложной зависимости от старого значения RAX, необходимо какое-то расширение до 32-разрядного.
Запись C таким образом вводит ICC в эту пропущенную оптимизацию, но не MSVC или clang.Они все еще оптимизируют это для расширения знака в первую очередь, потому что они знают, что XOR не может изменить какие-либо старшие биты.
int extend_after() {
char tmp = c^1;
return tmp;
}
теперь ICC похож на GCC, но по какой-то причине знак расширяется до 64-бит:
extend_after:
movzbl c(%rip), %eax #10.16
xorl $1, %eax #10.18
movsbq %al, %rax #11.12
ret #11.12