[Bug rtl-optimization/81538] Optimization problem compiling op.c (Perl_custom_op_get_field) in perl 5.26
danglin at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Aug 2 18:32:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81538
--- Comment #8 from John David Anglin <danglin at gcc dot gnu.org> ---
Created attachment 41897
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41897&action=edit
miniperl debug session
The flow and optimization of the Perl_custom_op_get_field function is quite
complex. Two switch statements are merged and it appears that ultimately the
wrong case is selected to load the return value.
On entry, register %r3 contains the value 0x5aedb0. %r3 is not modified
in the routine but it is eventually used to load the return value.
0x0001ab70 <Perl_custom_op_get_field+672>: ldw 10(r3),ret0
It seems there is some confusion as to where the variable xop resides. When
we hit the following statement, we have
14879 if(field == XOPe_xop_ptr) {(gdb) disass $pc-16,$pc+16
Dump of assembler code from 0x1aa28 to 0x1aa48:
0x0001aa28 <Perl_custom_op_get_field+344>: b,l 0x3b410,rp
0x0001aa2c <Perl_custom_op_get_field+348>: stw r0,0(r8)
0x0001aa30 <Perl_custom_op_get_field+352>: movb,<> ret0,r13,0x1aa74
<Perl_c
ustom_op_get_field+420>
0x0001aa34 <Perl_custom_op_get_field+356>: ldi 14,r25
=> 0x0001aa38 <Perl_custom_op_get_field+360>: cmpib,= 0,r5,0x1ab94
<Perl_custo
m_op_get_field+708>
0x0001aa3c <Perl_custom_op_get_field+364>: ldil L%186800,ret0
0x0001aa40 <Perl_custom_op_get_field+368>: ldo -1(r5),r5
0x0001aa44 <Perl_custom_op_get_field+372>: ldil L%1a800,ret0
End of assembler dump.
(gdb) info address xop
Symbol "xop" is multi-location:
Range 0x1a988-0x1a9a4: a variable in $r3
Range 0x1a9ac-0x1a9b8: a variable in $r3
Range 0x1aa38-0x1aa40: a complex DWARF expression:
0: DW_OP_addr 0x186a88
5: DW_OP_stack_value
Range 0x1aa44-0x1aa74: a variable in $r3
Range 0x1aa84-0x1ab94: a variable in $r3
Range 0x1ab94-0x1ab9c: a complex DWARF expression:
0: DW_OP_addr 0x186a88
5: DW_OP_stack_value
Range 0x1ab9c-0x1abb4: a variable in $r3
.
(gdb) p/x $r3
$2 = 0x5aedb0
(gdb) p xop
$3 = (XOP *) 0x186a88 <xop_null>
The variable he is always 0 in this call. So, nominally xop should point
at xop_null.
After we execute the switch statement, gdb thinks we are at line 14896:
(gdb) stepi
Perl_custom_op_get_field (my_perl=0x1e3008, o=0x5aee58, field=XOPe_xop_peep)
at op.c:14896
14896 break;
(gdb) disass $pc-16,$pc+16
Dump of assembler code from 0x1ab5c to 0x1ab7c:
0x0001ab5c <Perl_custom_op_get_field+652>: b,l 0x1a9b8
<Perl_custom_op_get_field+232>,r0
0x0001ab60 <Perl_custom_op_get_field+656>: ldw 8(r3),ret0
0x0001ab64 <Perl_custom_op_get_field+660>: b,l 0x1a9b8
<Perl_custom_op_get_field+232>,r0
0x0001ab68 <Perl_custom_op_get_field+664>: ldw 4(r3),ret0
=> 0x0001ab6c <Perl_custom_op_get_field+668>: b,l 0x1a9b8
<Perl_custom_op_get_field+232>,r0
0x0001ab70 <Perl_custom_op_get_field+672>: ldw 10(r3),ret0
0x0001ab74 <Perl_custom_op_get_field+676>: b,l 0x1a9b8
<Perl_custom_op_get_field+232>,r0
0x0001ab78 <Perl_custom_op_get_field+680>: ldw c(r3),ret0
Line 14896 is in the first switch expression. This should result in
xop->xop_peep being returned. However, here xop is supposed in register
%r3.
However, the flags value from xop_null is 0. So, the code should be
returning XOPd_xop_peep (ie., ((Perl_cpeep_t)0)).
More information about the Gcc-bugs
mailing list