James Molloy
2012-Dec-01 16:12 UTC
[LLVMdev] operator overloading fails while debugging with gdb for i386
Hi,
Structures are passed by pointer, so the return value is not actually in eax.
That code gets transformed into something like:
void sum(A1 *out, const A1 one, const A1 two) {
out->x = one.x + two.x
out->y = one.y + two.y
}
So actually the function ends up returning void and operating on a hidden
parameter, so %eax is dead at the end of the function and should not be being
relied upon by the calling code.
I believe this is a red-herring to whatever your actual bug is.
Cheers,
James
________________________________________
From: llvmdev-bounces at cs.uiuc.edu [llvmdev-bounces at cs.uiuc.edu] On Behalf
Of Mayur Pandey [mayurthebond at gmail.com]
Sent: 01 December 2012 11:13
To: llvmdev at cs.uiuc.edu
Subject: Re: [LLVMdev] operator overloading fails while debugging with gdb
for i386
Problem seems not only with operator overloading, It occurs with struct value
returning also.
gdb while debugging expects the return value in eax, gcc does returns in eax,
But Clang returns in edx(it can be checked in gdb by printing the contents of
edx).
Code(sample code)
struct A1 {
int x;
int y;
};
A1 sum(const A1 one, const A1 two)
{
A1 plus = {0,0};
plus.x = one.x + two.x;
plus.y = one.y + two.y;
return (plus);
}
int main (void)
{
A1 one= {2,3};
A1 two= {4,5};
A1 three = sum(one,two);
return 0;
}
gcc assembley (snippet of sum function)
_Z3sum2A1S_:
.loc 1 8 0
pushl %ebp
movl %esp, %ebp
.loc 1 9 0
movl 8(%ebp), %eax
movl $0, (%eax)
movl 8(%ebp), %eax
movl $0, 4(%eax)
.loc 1 10 0
movl 12(%ebp), %edx
movl 20(%ebp), %eax
addl %eax, %edx
movl 8(%ebp), %eax
movl %edx, (%eax)
.loc 1 11 0
movl 16(%ebp), %edx
movl 24(%ebp), %eax
addl %eax, %edx
movl 8(%ebp), %eax
movl %edx, 4(%eax)
.LBE2:
.loc 1 14 0
movl 8(%ebp), %eax
popl %ebp
ret $4
clang assembly (snippet of sum function)
_Z3sum2A1S_:
.loc 1 8 0
pushl %edi
pushl %esi
leal 24(%esp), %eax
leal 16(%esp), %ecx
movl 12(%esp), %edx
.loc 1 9 17 prologue_end
movl $0, 4(%edx)
movl $0, (%edx)
.loc 1 10 2
movl (%ecx), %esi
movl (%eax), %edi
addl %edi, %esi
movl %esi, (%edx)
.loc 1 11 2
movl 4(%ecx), %ecx
movl 4(%eax), %eax
addl %eax, %ecx
movl %ecx, 4(%edx)
.loc 1 13 2
popl %esi
popl %edi
ret $4
But while returning int value clang returns with eax... as expect. Problem comes
with when used struct/class
Is the behaviour of llvm as per the standards or is this a bug??
On Thu, Nov 29, 2012 at 12:40 PM, Mayur Pandey <mayurthebond at
gmail.com<mailto:mayurthebond at gmail.com>> wrote:
For the given test:
class A1 {
int x;
int y;
public:
A1(int a, int b)
{
x=a;
y=b;
}
A1 operator+(const A1&);
};
A1 A1::operator+(const A1& second)
{
A1 sum(0,0);
sum.x = x + second.x;
sum.y = y + second.y;
return (sum);
}
int main (void)
{
A1 one(2,3);
A1 two(4,5);
return 0;
}
when the exectable of this code is debugged in gdb for i386, we dont get the
expected results.
when we break at return 0; and give the command: print one + two, the result
should be $1 = {x = 6, y = 8}, but the result obtained is $1 = {x = 2, y = 3}.
This is related to debug information generated, as normally the overloading is
occuring.
eg: A1 three = one + two results {x = 6, y = 8}.
On checking the assembly, a suspicious entry is found which may be related for
the failure:
#DEBUG_VALUE: operator+:this <- undef
#DEBUG_VALUE: operator+:second <- undef
--
Thanx & Regards
Mayur Pandey
--
Thanx & Regards
Mayur Pandey
Mayur Pandey
2012-Dec-02 08:12 UTC
[LLVMdev] operator overloading fails while debugging with gdb for i386
Hi,
As you told that function ends up returning void, I just confirmed it in
the IR, the function is defined as:
define *void* @_Z3sum2A1S_(*%struct.A1* noalias sret %agg.result*,
%struct.A1* byval align 4 %one, %struct.A1* byval align 4 %two).
But when i checked the register values in g++, eax contains an address of
stack, which points to the value (object) returned by sum. That is if we
print the contents of the address stored in eax and contents of (address
stored in eax)+4, we get the correct value of sum. And GDB seems to print
from this only when we give the command print sum(one,two). { for clang
compiled code eax has some other value}
So is this just a coincidence for g++ that eax points to this address and
gdb prints the right value on the command print sum(one,two)??
On Sat, Dec 1, 2012 at 9:42 PM, James Molloy <James.Molloy at arm.com>
wrote:
> Hi,
>
> Structures are passed by pointer, so the return value is not actually in
> eax. That code gets transformed into something like:
>
> void sum(A1 *out, const A1 one, const A1 two) {
> out->x = one.x + two.x
> out->y = one.y + two.y
> }
>
> So actually the function ends up returning void and operating on a hidden
> parameter, so %eax is dead at the end of the function and should not be
> being relied upon by the calling code.
>
> I believe this is a red-herring to whatever your actual bug is.
>
> Cheers,
>
> James
> ________________________________________
> From: llvmdev-bounces at cs.uiuc.edu [llvmdev-bounces at cs.uiuc.edu] On
Behalf
> Of Mayur Pandey [mayurthebond at gmail.com]
> Sent: 01 December 2012 11:13
> To: llvmdev at cs.uiuc.edu
> Subject: Re: [LLVMdev] operator overloading fails while debugging with gdb
> for i386
>
> Problem seems not only with operator overloading, It occurs with struct
> value returning also.
>
> gdb while debugging expects the return value in eax, gcc does returns in
> eax, But Clang returns in edx(it can be checked in gdb by printing the
> contents of edx).
>
> Code(sample code)
>
> struct A1 {
> int x;
> int y;
> };
>
> A1 sum(const A1 one, const A1 two)
> {
> A1 plus = {0,0};
> plus.x = one.x + two.x;
> plus.y = one.y + two.y;
>
> return (plus);
> }
>
>
> int main (void)
> {
> A1 one= {2,3};
> A1 two= {4,5};
> A1 three = sum(one,two);
> return 0;
> }
>
>
> gcc assembley (snippet of sum function)
>
> _Z3sum2A1S_:
> .loc 1 8 0
> pushl %ebp
> movl %esp, %ebp
> .loc 1 9 0
> movl 8(%ebp), %eax
> movl $0, (%eax)
> movl 8(%ebp), %eax
> movl $0, 4(%eax)
> .loc 1 10 0
> movl 12(%ebp), %edx
> movl 20(%ebp), %eax
> addl %eax, %edx
> movl 8(%ebp), %eax
> movl %edx, (%eax)
> .loc 1 11 0
> movl 16(%ebp), %edx
> movl 24(%ebp), %eax
> addl %eax, %edx
> movl 8(%ebp), %eax
> movl %edx, 4(%eax)
> .LBE2:
> .loc 1 14 0
> movl 8(%ebp), %eax
> popl %ebp
> ret $4
>
> clang assembly (snippet of sum function)
> _Z3sum2A1S_:
> .loc 1 8 0
> pushl %edi
> pushl %esi
> leal 24(%esp), %eax
> leal 16(%esp), %ecx
> movl 12(%esp), %edx
> .loc 1 9 17 prologue_end
> movl $0, 4(%edx)
> movl $0, (%edx)
> .loc 1 10 2
> movl (%ecx), %esi
> movl (%eax), %edi
> addl %edi, %esi
> movl %esi, (%edx)
> .loc 1 11 2
> movl 4(%ecx), %ecx
> movl 4(%eax), %eax
> addl %eax, %ecx
> movl %ecx, 4(%edx)
> .loc 1 13 2
> popl %esi
> popl %edi
> ret $4
>
>
> But while returning int value clang returns with eax... as expect. Problem
> comes with when used struct/class
>
> Is the behaviour of llvm as per the standards or is this a bug??
>
>
>
>
>
>
>
>
>
> On Thu, Nov 29, 2012 at 12:40 PM, Mayur Pandey <mayurthebond at
gmail.com
> <mailto:mayurthebond at gmail.com>> wrote:
>
>
> For the given test:
>
> class A1 {
> int x;
> int y;
>
> public:
>
> A1(int a, int b)
> {
> x=a;
> y=b;
> }
>
> A1 operator+(const A1&);
> };
>
>
> A1 A1::operator+(const A1& second)
> {
> A1 sum(0,0);
> sum.x = x + second.x;
> sum.y = y + second.y;
>
> return (sum);
> }
>
>
> int main (void)
> {
> A1 one(2,3);
> A1 two(4,5);
>
> return 0;
> }
>
>
> when the exectable of this code is debugged in gdb for i386, we dont get
> the
> expected results.
>
> when we break at return 0; and give the command: print one + two, the
> result
> should be $1 = {x = 6, y = 8}, but the result obtained is $1 = {x = 2, y
> 3}.
>
> This is related to debug information generated, as normally the
> overloading is
> occuring.
> eg: A1 three = one + two results {x = 6, y = 8}.
>
>
> On checking the assembly, a suspicious entry is found which may be related
> for
> the failure:
>
> #DEBUG_VALUE: operator+:this <- undef
> #DEBUG_VALUE: operator+:second <- undef
>
>
> --
> Thanx & Regards
> Mayur Pandey
>
>
>
>
>
>
>
>
> --
> Thanx & Regards
> Mayur Pandey
>
>
>
>
>
>
>
--
Thanx & Regards
*Mayur Pandey *
Senior Software Engineer
Samsung India Software Operations
Bangalore
+91-9742959541
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20121202/31e6584c/attachment.html>
Renato Golin
2012-Dec-03 09:07 UTC
[LLVMdev] operator overloading fails while debugging with gdb for i386
On 2 December 2012 08:12, Mayur Pandey <mayurthebond at gmail.com> wrote:> So is this just a coincidence for g++ that eax points to this address and > gdb prints the right value on the command print sum(one,two)??The code is small, and the structure is probably set at the end of the block, so I think it's not that much of a coincidence. Regardless of the specific value on that specific compilation unit, you should never rely on behaviour of clobbered registers. That function returns void, you should look up in the caller, where is the address of the structure. Does the code execute correctly? Does a printf on the sum outputs the correct value? StrucRet is stable on Intel for years, I'd be surprised id that didn't work. However, it's possible that clang is messing up the position of the structure in Dwarf, so I'd investigate the Dwarf emission first, since your problem seems to bee with clang+gdb. -- cheers, --renato http://systemcall.org/
Reasonably Related Threads
- [LLVMdev] operator overloading fails while debugging with gdb for i386
- [LLVMdev] operator overloading fails while debugging with gdb for i386
- [LLVMdev] operator overloading fails while debugging with gdb for i386
- [LLVMdev] operator overloading fails while debugging with gdb for i386
- [LLVMdev] operator overloading fails while debugging with gdb for i386