[llvm-dev] Where's the optimiser gone (part 11): use the proper instruction for sign extension
Stefan Kanthak via llvm-dev
llvm-dev at lists.llvm.org
Sun Mar 3 23:06:13 PST 2019
Compile with -O3 -m32 (see <https://godbolt.org/z/yCpBpM>):
long lsign(long x)
{
return (x > 0) - (x < 0);
}
long long llsign(long long x)
{
return (x > 0) - (x < 0);
}
While the code generated for the "long" version of this function is quite
OK, the code for the "long long" version misses an obvious optimisation:
lsign: # @lsign
mov eax, dword ptr [esp + 4] | mov eax, dword ptr [esp + 4]
xor ecx, ecx |
test eax, eax | cdq
setg cl | neg eax
sar eax, 31 | adc edx, edx
add eax, ecx | mov eax, edx
ret | ret
llsign: # @llsign
xor ecx, ecx | xor edx, edx
mov eax, dword ptr [esp + 8] | mov eax, dword ptr [esp + 8]
cmp ecx, dword ptr [esp + 4] | cmp edx, dword ptr [esp + 4]
sbb ecx, eax | sbb edx, eax
setl cl | cdq
sar eax, 31 | setl al
movzx ecx, cl | movzx eax, al
add eax, ecx | add eax, edx
mov edx, eax | ret
sar edx, 31
ret
NOTE: not just here this sequence SHOULD be replaced with
mov edx, eax | cdq
sar edx, 31
Although CDQ is the proper instruction for sign extension, LLVM/clang doesn't
seem to like it.
stay tuned
Stefan Kanthak
More information about the llvm-dev
mailing list