[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