[Bug gdb/24530] doesn't understand vector double calling conventions on ppc64el

cel at us dot ibm.com sourceware-bugzilla@sourceware.org
Wed May 26 20:40:02 GMT 2021


https://sourceware.org/bugzilla/show_bug.cgi?id=24530

--- Comment #7 from Carl E Love <cel at us dot ibm.com> ---
I have discussed this issue with the IBM compiler team.  It seems that this is
an issue with the dwarf description not being able to correctly describe the
the vector variable in the function.  It is due to limitations in the ability
of dwarf to describe where the variable lives and when.  This is not an issue
that can be fixed with the current dwarf debug information.  It is actually an
area of on going research in how to track and describe the variables as a
result of the compiler optimizations.  It may be something that can be better
addressed in the future with newer dwarf versions.  It would probably require
changes in the dwarf spec, gcc to produce the enhanced dwarf information and
gdb.  It would be nice if gdb could handle this case better.

I will also note that I modified the given test program to try different vector
types and sizes.  The issue is common across all of the vector types and sizes
I tested including vector types: double, unsigned long long, char.

Also note that I played with adding additional lines of code to the function
addD to do computations to compute a new value of one[0] and one[1] before
doing "one + two". 

v2f64  __attribute__ ((noinline)) addD(v2f64 one, v2f64 two) {
  one[0] = one[0]+ two[1];
  one[1] = one[1]+ two[0];
return one + two;
}

When I run gdb on the new test I get:

(gdb) break addD
Breakpoint 1 at 0x100006b0: file gdb-issue30_test-v5.c, line 7.
(gdb) r
Starting program: /home/carll/GDB/Tests/gdb-issue30_test-v5-O3 

Breakpoint 1, addD (one=..., two=...) at gdb-issue30_test-v5.c:7
7         one[0] = one[0]+ two[1];
(gdb) p one
$1 = {1.1067070466843923e-321, -4.634680647717764e+158}
(gdb) p two
$2 = {1.1067070466843923e-321, -4.634680647717764e+158}
(gdb) s
9       return one + two;
(gdb) p one
$3 = <optimized out>
(gdb) p two
$4 = {1.1067070466843923e-321, -4.634680647717764e+158}

Having gdb print "optimized out" is preferable to printing garbage.

Again, this points to the dwarf not being able to correctly/precisely state
where the values are stored and when they are valid.


For the record, here are some detailed notes I made while investigating the
issue with the original test case given in the bugzilla.

When the test case is compiled with default optimization gdb correctly displays
the values for variables one and two in the routine addD().  But with -O3 gdb
does not correctly display the variables in addD().  gdb appears to print 
garbage.

When you run "readelf --debug-dump=info a.out-default" where a.out-default is
the binary produced with default optimization the dwarf entries for the
variables are:

<2><60e>: Abbrev Number: 8 (DW_TAG_variable)
    <60f>   DW_AT_name        : one
    <613>   DW_AT_decl_file   : 1
    <614>   DW_AT_decl_line   : 11
    <615>   DW_AT_decl_column : 7
    <616>   DW_AT_type        : <0x5cd>
    <61a>   DW_AT_location    : 2 byte block: 91 40     (DW_OP_fbreg: -64)
 <2><61d>: Abbrev Number: 8 (DW_TAG_variable)
    <61e>   DW_AT_name        : two
    <622>   DW_AT_decl_file   : 1
    <623>   DW_AT_decl_line   : 12
    <624>   DW_AT_decl_column : 7
    <625>   DW_AT_type        : <0x5cd>
    <629>   DW_AT_location    : 2 byte block: 91 50     (DW_OP_fbreg: -48)

When you run "readelf --debug-dump=info a.out-O3 > out-O3" where out-O3 is the
binary produced with -O3 optimization, the dwarf entries for the variables are:

 <2><60a>: Abbrev Number: 8 (DW_TAG_variable)
    <60b>   DW_AT_name        : one
    <60f>   DW_AT_decl_file   : 1
    <610>   DW_AT_decl_line   : 11
    <611>   DW_AT_decl_column : 7
    <612>   DW_AT_type        : <0x5c9>
    <616>   DW_AT_location    : 0x2 (location list)
    <61a>   DW_AT_GNU_locviews: 0x0
 <2><61e>: Abbrev Number: 8 (DW_TAG_variable)
    <61f>   DW_AT_name        : two
    <623>   DW_AT_decl_file   : 1
    <624>   DW_AT_decl_line   : 12
    <625>   DW_AT_decl_column : 7
    <626>   DW_AT_type        : <0x5c9>
    <62a>   DW_AT_location    : 0x3e (location list)
    <62e>   DW_AT_GNU_locviews: 0x3c


In the optimized code, the vectors are loaded in the mainline code and the
subroutine operates directly on the vectors.  The parameters are not
stored/fetched from the stack as can be seen in the assembly dumps below.


default gcc optimized assembly code:

typedef double v2f64 __attribute__((vector_size(16)));

v2f64  __attribute__ ((noinline)) addD(v2f64 one, v2f64 two) {
    1000063c:   f8 ff e1 fb     std     r31,-8(r1)
    10000640:   b1 ff 21 f8     stdu    r1,-80(r1)
    10000644:   78 0b 3f 7c     mr      r31,r1
    10000648:   56 12 02 f0     xxswapd vs0,vs34
    1000064c:   20 00 20 39     li      r9,32
    10000650:   98 4f 1f 7c     stxvd2x vs0,r31,r9
    10000654:   56 1a 03 f0     xxswapd vs0,vs35
    10000658:   30 00 20 39     li      r9,48
    1000065c:   98 4f 1f 7c     stxvd2x vs0,r31,r9
return one + two;
    10000660:   20 00 20 39     li      r9,32
    10000664:   98 4e 1f 7c     lxvd2x  vs0,r31,r9
    10000668:   50 02 80 f1     xxswapd vs12,vs0
    1000066c:   30 00 20 39     li      r9,48
    10000670:   98 4e 1f 7c     lxvd2x  vs0,r31,r9
    10000674:   50 02 00 f0     xxswapd vs0,vs0
    10000678:   00 03 0c f0     xvadddp vs0,vs12,vs0
}

int main() {
    10000698:   02 10 40 3c     lis     r2,4098
    1000069c:   00 7f 42 38     addi    r2,r2,32512
    100006a0:   a6 02 08 7c     mflr    r0
    100006a4:   10 00 01 f8     std     r0,16(r1)
    100006a8:   f8 ff e1 fb     std     r31,-8(r1)
    100006ac:   61 ff 21 f8     stdu    r1,-160(r1)
    100006b0:   78 0b 3f 7c     mr      r31,r1
v2f64 one = {1.5, 2.5};
    100006b4:   fe ff 22 3d     addis   r9,r2,-2
    100006b8:   20 8a 29 39     addi    r9,r9,-30176
    100006bc:   98 4e 00 7c     lxvd2x  vs0,0,r9
    100006c0:   50 02 00 f0     xxswapd vs0,vs0
    100006c4:   50 02 00 f0     xxswapd vs0,vs0
    100006c8:   60 00 20 39     li      r9,96
    100006cc:   98 4f 1f 7c     stxvd2x vs0,r31,r9
v2f64 two = {3.5, 4.5};
    100006d0:   fe ff 22 3d     addis   r9,r2,-2
    100006d4:   30 8a 29 39     addi    r9,r9,-30160
    100006d8:   98 4e 00 7c     lxvd2x  vs0,0,r9
    100006dc:   50 02 00 f0     xxswapd vs0,vs0
    100006e0:   50 02 00 f0     xxswapd vs0,vs0
    100006e4:   70 00 20 39     li      r9,112
    100006e8:   98 4f 1f 7c     stxvd2x vs0,r31,r9
v2f64 res = addD(one, two);
    100006ec:   70 00 20 39     li      r9,112
    100006f0:   98 4e 1f 7c     lxvd2x  vs0,r31,r9
    100006f4:   51 02 60 f0     xxswapd vs35,vs0
    100006f8:   60 00 20 39     li      r9,96
    100006fc:   98 4e 1f 7c     lxvd2x  vs0,r31,r9
    10000700:   51 02 40 f0     xxswapd vs34,vs0
    10000704:   39 ff ff 4b     bl      1000063c <addD>
    ....


The gcc assembly for the -O3 code:

00000000100004c0 <main>:

00000000100006b0 <addD>:
}
    100006b0:   07 1b 42 f0     xvadddp vs34,vs34,vs35
    100006b4:   20 00 80 4e     blr
     ...

int main() {
    100004c0:   02 10 40 3c     lis     r2,4098
    100004c4:   00 7f 42 38     addi    r2,r2,32512
    100004c8:   a6 02 08 7c     mflr    r0
v2f64 one = {1.5, 2.5};
v2f64 two = {3.5, 4.5};
v2f64 res = addD(one, two);
    100004cc:   fe ff 42 3d     addis   r10,r2,-2
    100004d0:   fe ff 22 3d     addis   r9,r2,-2
    100004d4:   60 89 4a 39     addi    r10,r10,-30368
    100004d8:   70 89 29 39     addi    r9,r9,-30352
int main() {
    100004dc:   10 00 01 f8     std     r0,16(r1)
    100004e0:   a1 ff 21 f8     stdu    r1,-96(r1)
v2f64 res = addD(one, two);
    100004e4:   ce 50 60 7c     lvx     v3,0,r10
    100004e8:   ce 48 40 7c     lvx     v2,0,r9
    100004ec:   c5 01 00 48     bl      100006b0 <addD>
    ....

Based on my current understanding, I do not believe this is an issue that can
be properly addressed and fixed with the current dwarf.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Gdb-prs mailing list