Meador Inge
2012-Feb-09 02:49 UTC
[LLVMdev] x86-64 sign extension for parameters and return values
I recently noticed a difference between the way GCC and LLVM treat sign extension for parameters and return values on x86-64. I could not find a clear answer in the x86-64 ABI [1] concerning whether parameters should be sign extended by the caller or callee and similarly whether return values should be sign extended by the caller or callee. Consider a simple 'signed char' division routine: signed char sdiv(signed char x, signed char y) { return x / y; } On my Fedora 16 Linux host GCC 4.6.2 produces: sdiv: .LFB11: .cfi_startproc movsbl %dil, %eax movsbl %sil, %esi movl %eax, %edx sarl $31, %edx idivl %esi ret where as clang 2.9 produces: sdiv: # @sdiv .Leh_func_begin0: # BB#0: movl %edi, %eax cltd idivl %esi movsbl %al, %eax ret GCC assumes the parameters have *not* been sign extended and assumes it is the receivers job to extend the return value. LLVM assumes the parameters *have* been sign extended and that the receiver expects a sign extended result. The LLVM model implies the the caller always has to sign extend for signed promotion to argument registers and that the callee always has to sign extend for signed promotion to return value registers. The GCC model seems more reasonable and efficient to me because whoever is actually using the values gets to choose whether a sign extension is done (or not done at all). Could someone explain the LLVM implementation to me? [1] http://www.x86-64.org/documentation/abi.pdf -- # Meador
Eli Friedman
2012-Feb-23 21:54 UTC
[LLVMdev] x86-64 sign extension for parameters and return values
On Wed, Feb 8, 2012 at 6:49 PM, Meador Inge <meadori at gmail.com> wrote:> I recently noticed a difference between the way GCC and LLVM treat > sign extension for parameters and return values on x86-64. I could > not find a clear answer in the x86-64 ABI [1] concerning whether > parameters should be sign extended by the caller or callee and > similarly whether return values should be sign extended by the caller > or callee. > > Consider a simple 'signed char' division routine: > > signed char sdiv(signed char x, signed char y) > { > return x / y; > } > > On my Fedora 16 Linux host GCC 4.6.2 produces: > > sdiv: > .LFB11: > .cfi_startproc > movsbl %dil, %eax > movsbl %sil, %esi > movl %eax, %edx > sarl $31, %edx > idivl %esi > ret > > where as clang 2.9 produces: > > sdiv: # @sdiv > .Leh_func_begin0: > # BB#0: > movl %edi, %eax > cltd > idivl %esi > movsbl %al, %eax > ret > > GCC assumes the parameters have *not* been sign extended and assumes > it is the receivers job to extend the return value. LLVM assumes the > parameters *have* been sign extended and that the receiver expects a > sign extended result. > > The LLVM model implies the the caller always has to sign extend for > signed promotion to argument registers and that the callee always has > to sign extend for signed promotion to return value registers. The > GCC model seems more reasonable and efficient to me because whoever is > actually using the values gets to choose whether a sign extension is > done (or not done at all). > > Could someone explain the LLVM implementation to me? > > [1] http://www.x86-64.org/documentation/abi.pdfSorry about the delayed response; I was sort of expecting someone else to respond. It looks like a rather nasty issue, and deserves some attention. LLVM has traditionally assumed that all integer argument and return types narrower than int are promoted to int on all architectures. Nobody has actually noticed any issues with this before now, as far as I know. If gcc has decided to assume no sign/zero-extension on x86-64, we need to follow their lead, at least on Linux. Please file at http://llvm.org/bugs/ ; an executable testcase to go with this would be nice, so we can compare various compilers and different platforms. (clang 2.9 relatively old, but I don't think anything has changed here since it was released.) -Eli
Chris Lattner
2012-Feb-23 23:08 UTC
[LLVMdev] x86-64 sign extension for parameters and return values
On Feb 23, 2012, at 1:54 PM, Eli Friedman wrote:>> The LLVM model implies the the caller always has to sign extend for >> signed promotion to argument registers and that the callee always has >> to sign extend for signed promotion to return value registers. The >> GCC model seems more reasonable and efficient to me because whoever is >> actually using the values gets to choose whether a sign extension is >> done (or not done at all). >> >> Could someone explain the LLVM implementation to me? >> >> [1] http://www.x86-64.org/documentation/abi.pdf > > Sorry about the delayed response; I was sort of expecting someone else > to respond. It looks like a rather nasty issue, and deserves some > attention. > > LLVM has traditionally assumed that all integer argument and return > types narrower than int are promoted to int on all architectures. > Nobody has actually noticed any issues with this before now, as far as > I know.FYI, this is vaguely related: http://nondot.org/~sabre/LLVMNotes/ExtendedIntegerResults.txt It was brought up by people that cared about 16-bit targets but where int was 32-bit. I don't think that anyone actively cares about this at the moment, but it would be nice to clean this up someday. -Chris
Meador Inge
2012-Feb-23 23:11 UTC
[LLVMdev] x86-64 sign extension for parameters and return values
On Thu, Feb 23, 2012 at 3:54 PM, Eli Friedman <eli.friedman at gmail.com> wrote:> LLVM has traditionally assumed that all integer argument and return > types narrower than int are promoted to int on all architectures. > Nobody has actually noticed any issues with this before now, as far as > I know.The only reason that I noticed was that Python ctypes started misbehaving when we went to build/test it on OS X Lion (http://bugs.python.org/issue13370). After investigating the failure I found this. Python uses libffi and libffi implements the GCC ABI. So I would expect any project using libffi with clang to have problems.> If gcc has decided to assume no sign/zero-extension on x86-64, we need > to follow their lead, at least on Linux. Please file at > http://llvm.org/bugs/ ; an executable testcase to go with this would > be nice, so we can compare various compilers and different platforms.Will do. Thanks. -- Meador
Reasonably Related Threads
- [LLVMdev] x86-64 sign extension for parameters and return values
- [LLVMdev] x86-64 sign extension for parameters and return values
- [LLVMdev] x86-64 sign extension for parameters and return values
- [LLVMdev] equivalent IR, different asm
- [LLVMdev] equivalent IR, different asm