|
From: | Shasank Chavan |
Subject: | [Dotgnu-libjit] Bug involving register allocation after implicit integer promotion. |
Date: | Tue, 13 Jul 2010 18:25:01 -0700 |
Hi. I'm still fairly new to libjit, and so forgive me if I misstate a few things. The following looks to be a bug that, *hopefully* has already been fixed. I have what I believe to be the latest available libjit library (libjit-0.1.2), but maybe not. I'm running libjit on a linux 64-bit system, but I'm generating IA32 x86 code. Basically I have an add instruction which requires one of the operands (a 32-bit value) to be promoted to 64-bits before the add occurs. Subsequently the 32-bit value is reused in a convert for storage. The libjit library generates good IL for this, but the generated code ends up using the wrong register when reusing the 32-bit value. I'll explain below, as it is a simple program and easy to reproduce: I make the following simples calls to generate my function (minus all the pre-header stuff to set up the function and all of that): // temp1 = *((long long*)s) // temp2 = *((int*)(s+8)) // temp3 = temp1 + temp2; // *(s+12) = temp3 temp1 = jit_insn_load_relative(function, s, 0, jit_type_long); temp2 = jit_insn_load_relative(function, s, 8, jit_type_int); temp3 = jit_insn_add(function, temp1, temp2); jit_insn_store_relative(function, s, 12, temp3); // temp4 = ((long long) temp2) // *(t) = temp4 temp4 = jit_insn_convert(function, temp2, jit_type_long, 0); jit_insn_store_relative(function, t, 0, temp4); This generates the following IL and Assembly: function Your Mom(l1 : ulong, i2 : int, d3 : float64, i4 : ptr, i5 : ptr) : int incoming_frame_posn(l1, 8) incoming_frame_posn(i2, 16) incoming_frame_posn(d3, 20) incoming_frame_posn(i4, 28) incoming_frame_posn(i5, 32) l15 = load_relative_long(i4, 0) i17 = load_relative_int(i4, 8) l18 = expand_int(i17) l19 = l15 + l18 store_relative_long(i4, l19, 12) l21 = expand_int(i17) store_relative_long(i5, l21, 0) return_int(0) ends_in_dead end And the assembly is: Disassembly of section .text: fffffffff7f79018 <.text>: fffffffff7f79018: 55 push %rbp fffffffff7f79019: 8b ec mov %esp,%ebp fffffffff7f7901b: 83 ec 04 sub $0x4,%esp fffffffff7f7901e: 53 push %rbx fffffffff7f7901f: 56 push %rsi fffffffff7f79020: 8b 4d 1c mov 0x1c(%rbp),%ecx fffffffff7f79023: 8b 01 mov (%rcx),%eax fffffffff7f79025: 8b 51 04 mov 0x4(%rcx),%edx fffffffff7f79028: 8b 59 08 mov 0x8(%rcx),%ebx fffffffff7f7902b: 89 5d fc mov %ebx,0xfffffffffffffffc(%rbp) fffffffff7f7902e: 8b f3 mov %ebx,%esi fffffffff7f79030: 8b ce mov %esi,%ecx fffffffff7f79032: 8b d9 mov %ecx,%ebx fffffffff7f79034: c1 fb 1f sar $0x1f,%ebx fffffffff7f79037: 03 c1 add %ecx,%eax fffffffff7f79039: 13 d3 adc %ebx,%edx fffffffff7f7903b: 8b 4d 1c mov 0x1c(%rbp),%ecx fffffffff7f7903e: 89 41 0c mov %eax,0xc(%rcx) fffffffff7f79041: 89 51 10 mov %edx,0x10(%rcx) fffffffff7f79044: 8b c3 mov %ebx,%eax fffffffff7f79046: 8b d0 mov %eax,%edx fffffffff7f79048: c1 fa 1f sar $0x1f,%edx fffffffff7f7904b: 8b 4d 20 mov 0x20(%rbp),%ecx fffffffff7f7904e: 89 01 mov %eax,(%rcx) fffffffff7f79050: 89 51 04 mov %edx,0x4(%rcx) fffffffff7f79053: 33 c0 xor %eax,%eax fffffffff7f79055: 5e pop %rsi fffffffff7f79056: 5b pop %rbx fffffffff7f79057: 8b e5 mov %ebp,%esp fffffffff7f79059: 5d pop %rbp fffffffff7f7905a: c3 retq end When the 32-bit value is sign extended via the sar instruction, the new upper 32-bits are stored back into the same register ($ebx). Later, when applying the convert, $ebx is used to represent the original 32-bit value, and that's wrong, as $ebx has since been cleared out. It does seem like $ebx was correctly spilled to memory prior to the integer promotion involving the add, but that value never gets reloaded from memory. Please let me know if I need to provide more information. Thanks. - Shasank Hotmail is redefining busy with tools for the New Busy. Get more from your inbox. See how. |
[Prev in Thread] | Current Thread | [Next in Thread] |