[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